มีวิธีการตรวจสอบหมายเลขบรรทัดของbash
สคริปต์ที่จะถูกดำเนินการ "ตอนนี้"?
การใช้bash -x script.sh
รูปลักษณ์ที่ดูดี อย่างไรก็ตามฉันต้องได้รับหมายเลขบรรทัดปัจจุบัน
มีวิธีการตรวจสอบหมายเลขบรรทัดของbash
สคริปต์ที่จะถูกดำเนินการ "ตอนนี้"?
การใช้bash -x script.sh
รูปลักษณ์ที่ดูดี อย่างไรก็ตามฉันต้องได้รับหมายเลขบรรทัดปัจจุบัน
คำตอบ:
$ cat test.sh
#!/usr/bin/env bash
set -x
PS4='+${LINENO}: '
sleep 1m
sleep 1d
$ timeout 5 ./test.sh
+3: PS4='+${LINENO}: '
+5: sleep 1m
หรือในเปลือกแม่ :
$ cat test.sh
sleep 1m
sleep 1d
$ export PS4='+${LINENO}: '
$ timeout 5 bash -x ./test.sh
+1: sleep 1m
ใช่มีวิธี
มีอาร์เรย์ของหมายเลขบรรทัดที่ฟังก์ชันถูกเรียกใช้
กำหนดฟังก์ชั่นนี้:
f(){ echo "${BASH_LINENO[-2]}"; }
และโทรไปf
ที่สายใดก็ได้ที่คุณต้องการหมายเลขบรรทัดตัวอย่างเช่น:
#!/bin/bash
f(){ echo "${BASH_LINENO[-2]}"; }
f
echo next1
f
echo next2
f
echo next 3
f
จะพิมพ์:
6
next 1
9
next 2
12
next 3
15
สามารถขยายเพื่อแสดงเส้นทางของฟังก์ชันที่เรียกว่า:
#!/bin/bash
f(){
for ((i=${#BASH_LINENO[@]}-1;i>=0;i--)); do
printf '<%s:%s> ' "${FUNCNAME[i]}" "${BASH_LINENO[i]}";
done
echo "$LINENO"
}
SomeOtherFunction(){ echo -n "test the line numbering: "; f; }
f
echo next 1
echo -n " This line numbering: "; f
SomeOtherFunction
echo next 2
echo -n " This line numbering: "; f
SomeOtherFunction
echo next 3
echo -n " This line numbering: "; f
สิ่งที่จะพิมพ์:
$ ./script
<main:0> <f:12> 7
next 1
This line numbering: <main:0> <f:15> 7
test the line numbering: <main:0> <SomeOtherFunction:16> <f:10> 7
next 2
This line numbering: <main:0> <f:19> 7
test the line numbering: <main:0> <SomeOtherFunction:20> <f:10> 7
next 3
This line numbering: <main:0> <f:23> 7
โปรดทราบว่าเหนือecho "$LINENO"
ผลลัพธ์จะเหมือนกันเสมอ (7 ในกรณีนี้)
นี่คือทางออกที่ยืมชิ้นส่วนของl0b0 ของและDopeGhoti ของคำตอบ (และในระดับน้อย, sorontar ของ ) เช่นเดียวกับคำตอบเหล่านั้นฉันใช้$LINENO
เพื่อค้นหาหมายเลขบรรทัด; ฉันใช้trap
เพื่อกระตุ้นการรายงาน trap
คำสั่งของ bash อธิบายไว้ในbash (1) :
trap [-lp] [[arg] sigspec ...]
คำสั่งหาเรื่องคือการอ่านและดำเนินการเมื่อเปลือกได้รับสัญญาณ (s) sigspec ... ︙
... ถ้าsigspecเป็นDEBUGคำสั่งหาเรื่องจะถูกดำเนินการก่อนที่ทุกคำสั่งง่ายๆ ,for
คำสั่งcase
คำสั่งselect
คำสั่งทุกเลขคณิตfor
คำสั่งและก่อนที่จะรันคำสั่งแรกในฟังก์ชั่นเชลล์ ...
ดังนั้นสคริปต์นี้:
$ cat -n myscript
1 #!/bin/bash
2 trap 'printf "%3d: " "$LINENO"' DEBUG
3 date
4 sleep 30
5 date
6 sleep \
7 11
8 date
9
10 ls -l
11 for f in *
12 do
13 echo "$f" &&
14 ls -ld "$f"
15 done
16
17 for ((i=0; i<3; i++))
18 do
19 echo "i = $i"; date
20 done
21
22 echo $((5+25+12))
$
รันprintf "%3d: " "$LINENO"
คำสั่งก่อนทุกคำสั่งในสคริปต์และสร้างเอาต์พุตนี้:
$ ./myscript 3: พุธ, 5 เม.ย. 2017 10:16:17 น 4: 5: พุธ, 5 เม.ย. 2017 10:16:47 น 7: 8: พุธ, 5 เม.ย. 2017 10:16:58 AM 10: รวม 4 -rwxr-xr-x 1 myusername mygroup 221 เม.ย. 5 10:01 myscript -rwxr-xr-x 1 myusername mygroup 252 5 เม.ย. 10:01 myscript2 -rw-r - r-- 1 myusername mygroup 132 เม.ย. 5 09:59 myscript2.log -rw-r - r-- 1 myusername mygroup 45 เม.ย. 5 08:34 other_file 11: 13: myscript 14: -rwxr-xr-x 1 myusername mygroup 221 เม.ย. 5 10:01 myscript 11: 13: myscript2 14: -rwxr-xr-x 1 myusername mygroup 252 5 เม.ย. 10:01 myscript2 11: 13: myscript2.log 14: -rw-r - r-- 1 myusername mygroup 132 เม.ย. 5 09:59 myscript2.log 11: 13: other_file 14: -rw-r - r-- 1 myusername mygroup 45 เม.ย. 5 08:34 other_file 17: 17: 19: i = 0 19: พุธ, 5 เม.ย. 2017 10:16:59 AM 17: 17: 19: i = 1 19: พุธ, 5 เม.ย. 2017 10:16:59 AM 17: 17: 19: i = 2 19: พุธ, 5 เม.ย. 2017 10:16:59 AM 17: 17: 22: 42 $
หมายเหตุ:
sleep
ซึ่งครอบคลุมสคริปต์บรรทัด 6 และ 7 ถูกรายงานเป็นบรรทัด 7for f in *
มีการรายงานบรรทัดที่ 11 ( ) หนึ่งครั้งก่อนการวนซ้ำแต่ละครั้งของfor
ลูปนั้นecho "$f"
และls -ld "$f"
มีการรายงานอย่างถูกต้องในบรรทัดที่เกี่ยวข้อง (13 และ 14)for ((i=0; i<3; i++))
) จะถูกรายงานสองครั้ง
ก่อนการวนซ้ำแต่ละครั้งของการวนซ้ำนั้นfor
และอีกสองครั้งหลังจากการทำซ้ำครั้งสุดท้ายset -x
, LINENO
และPS4
(ซึ่งถูกกำหนดโดยมาตรฐาน POSIX) ดีบักtrap
เป็นส่วนขยายทุบตีและจะไม่ทำงานในเปลือกหอยทั้งหมดtrap
สามารถเรียกใช้คำสั่งใด ๆ และไม่ จำกัด เฉพาะการเขียนไปยังเอาต์พุตมาตรฐานของสคริปต์หรือข้อผิดพลาดมาตรฐานคำถามบอกว่า«ตรวจสอบหมายเลขบรรทัดของสคริปต์ทุบตีที่จะถูกดำเนินการ "ตอนนี้" »โดยไม่ต้องระบุส่วนติดต่อผู้ใช้ อีกวิธีหนึ่งคือการเขียนหมายเลขบรรทัดปัจจุบันไปยังไฟล์บันทึกอย่างต่อเนื่อง:
$ diff myscript myscript2 2c2 <trap 'printf "% 3d:" "$ LINENO"' DEBUG --- > exec 6> myscript2.log && trap 'printf "% 3d \ n" "$ LINENO"> & 6' DEBUG $ ./myscript2 พุธ, 05 เม.ย. 2017 10:23:50 น พุธ, 05 เม.ย. 2017 10:24:20 AM พุธ, 05 เม.ย. 2017 10:24:31 AM รวม 4 -rwxr-xr-x 1 myusername mygroup 221 เม.ย. 5 10:01 myscript -rwxr-xr-x 1 myusername mygroup 252 5 เม.ย. 10:01 myscript2 -rw-r - r-- 1 myusername mygroup 24 เม.ย. 5 10:23 myscript2.log -rw-r - r-- 1 myusername mygroup 45 เม.ย. 5 08:34 other_file MyScript -rwxr-xr-x 1 myusername mygroup 221 เม.ย. 5 10:01 myscript myscript2 -rwxr-xr-x 1 myusername mygroup 252 5 เม.ย. 10:01 myscript2 myscript2.log -rw-r - r-- 1 myusername mygroup 60 เม.ย. 5 10:23 myscript2.log other_file -rw-r - r-- 1 myusername mygroup 45 เม.ย. 5 08:34 other_file i = 0 พุธ, 05 เม.ย. 2017 10:24:31 AM i = 1 พุธ, 05 เม.ย. 2017 10:24:31 AM i = 2 พุธ, 05 เม.ย. 2017 10:24:31 AM 42 $
เราสามารถตรวจสอบการทำงานของสคริปต์นี้โดยการตรวจสอบเนื้อหาของmyscript2.log
ไฟล์จากเทอร์มินัลอื่น ยกตัวอย่างเช่นในช่วงที่สองsleep
,
$ tail myscript2.log
3
4
5
7
คุณสามารถecho $LINENO
ในสคริปต์และมันควรจะออกบรรทัดใด ๆ ที่คำสั่งที่เกิดขึ้นจะอยู่ใน
#!/bin/bash
echo $LINENO
$ ./foo.sh
2
#!/bin/bash -x
เพิ่ม "-x" ตอนเริ่มต้นสคริปต์ของคุณ จากนั้นทุกครั้งที่คุณเรียกใช้งานสคริปต์สคริปต์จะแสดงบรรทัดที่สคริปต์ของคุณดำเนินการอยู่ เหมือนต้นไม้ดำเนินการของสคริปต์ของคุณ