ฉันใช้ Ubuntu 10.10 กับ openbox ที่ทำงานอยู่ด้านบน ฉันสังเกตเห็นคำสั่งวันนี้ที่เรียกว่าcaller
แต่ไม่มีหน้าคนมันไม่ตอบสนองต่อการป้อนข้อมูลใด ๆ (หรือ - ช่วย) และที่ไม่พบมัน
ความคิดอะไรมันคืออะไร?
ฉันใช้ Ubuntu 10.10 กับ openbox ที่ทำงานอยู่ด้านบน ฉันสังเกตเห็นคำสั่งวันนี้ที่เรียกว่าcaller
แต่ไม่มีหน้าคนมันไม่ตอบสนองต่อการป้อนข้อมูลใด ๆ (หรือ - ช่วย) และที่ไม่พบมัน
ความคิดอะไรมันคืออะไร?
คำตอบ:
วิ่ง
type caller
และคุณจะเห็นว่ามันเป็นเปลือกในตัว วิ่ง
help caller
จะแสดงฟังก์ชั่นรายงานเช่นกันในหน้าคู่มือของ bash สั้น
Return the context of the current subroutine call.
help
คำสั่งในตัว
type type
, type help
, help type
และhelp help
อาจจะสนุกกับการทำงาน :)
caller
เป็นคำสั่งในตัว (ไม่ได้ระบุไว้โดย POSIX) ปรากฏในทุบตีรุ่น 3.0 และจะส่งกลับบริบทของการโทร subroutine ใด ๆ ที่ใช้งานอยู่ ดู: Bash-Builtinsสำหรับการอ่านเพิ่มเติม
ไวยากรณ์:
caller [FRAMENUMBER]
หากมีการระบุหมายเลขเฟรมเป็นจำนวนเต็มที่ไม่เป็นลบจะแสดงหมายเลขบรรทัดชื่อรูทีนย่อยและไฟล์ต้นฉบับที่สอดคล้องกับตำแหน่งนั้นในสแตกการเรียกใช้งานปัจจุบัน
หากไม่มีพารามิเตอร์ใด ๆผู้เรียกจะแสดงหมายเลขบรรทัดและชื่อไฟล์ต้นทางของการเรียกรูทีนย่อยปัจจุบัน
ตรวจสอบSimple stack traceต่อไปนี้ที่ Bash Hackers Wiki :
#!/bin/bash
die() {
local frame=0
while caller $frame; do
((frame++));
done
echo "$*"
exit 1
}
f1() { die "*** an error occured ***"; }
f2() { f1; }
f3() { f2; }
f3
เอาท์พุท:
12 f1 ./callertest.sh
13 f2 ./callertest.sh
14 f3 ./callertest.sh
16 main ./callertest.sh
*** an error occured ***
นี่คือตัวอย่างของdie
ฟังก์ชันที่เหมาะสมในการติดตามข้อผิดพลาดในสคริปต์ที่ซับซ้อนปานกลาง:
{ bash /dev/stdin; } <<<$'f(){ g; }\ng(){ h; }\nh(){ while caller $((n++)); do :; done; }\nf'
สำหรับการดีบักที่ซับซ้อนยิ่งขึ้นคุณลักษณะการดีบักแบบขยายของ Bash จะพร้อมใช้งานและพารามิเตอร์พิเศษจำนวนหนึ่งที่ให้รายละเอียดมากกว่าตัวเรียก (เช่น
BASH_ARG{C,V}
) เครื่องมือต่าง ๆ เช่นBashdbสามารถช่วยในการใช้คุณสมบัติการดีบักขั้นสูงของ Bash
มันเป็นคำสั่ง shell builtin: man bash
(จากนั้นค้นหา 'ผู้โทร')
มันสามารถใช้เพื่อพิมพ์การติดตามสแต็ก
โปรดทราบว่าคุณสามารถread
ส่งออกcaller
เป็นตัวแปรเพื่อควบคุมวิธีการจัดรูปแบบผลลัพธ์:
stacktrace() {
local frame=0 LINE SUB FILE
while read LINE SUB FILE < <(caller "$frame"); do
echo "${SUB} @ ${FILE}:${LINE}"
((frame++))
done
}
การสาธิต:
$ cat /tmp/caller.sh
#!/bin/bash
stacktrace() {
local frame=0 LINE SUB FILE
while read LINE SUB FILE < <(caller "$frame"); do
printf ' %s @ %s:%s' "${SUB}" "${FILE}" "${LINE}"
((frame++))
done
}
die() {
echo "$*"
stacktrace
exit 1
}
f1() { die "*** an error occured ***"; }
f2() { f1; }
f3() { f2; }
f3
$ bash /tmp/caller.sh
*** an error occured ***
die @ /tmp/caller.sh:13
f1 @ /tmp/caller.sh:17
f2 @ /tmp/caller.sh:18
f3 @ /tmp/caller.sh:19
main @ /tmp/caller.sh:21