คำสั่ง“ ผู้โทร” คืออะไร?


12

ฉันใช้ Ubuntu 10.10 กับ openbox ที่ทำงานอยู่ด้านบน ฉันสังเกตเห็นคำสั่งวันนี้ที่เรียกว่าcallerแต่ไม่มีหน้าคนมันไม่ตอบสนองต่อการป้อนข้อมูลใด ๆ (หรือ - ช่วย) และที่ไม่พบมัน

ความคิดอะไรมันคืออะไร?

คำตอบ:


16

วิ่ง

type caller

และคุณจะเห็นว่ามันเป็นเปลือกในตัว วิ่ง

help caller

จะแสดงฟังก์ชั่นรายงานเช่นกันในหน้าคู่มือของ bash สั้น

Return the context of the current subroutine call.


3
น่ากลัว ไม่เพียง แต่ฉันเรียนรู้ว่าคำสั่งนั้นทำอะไรฉันยังได้เรียนรู้คำสั่ง "type" ขอบคุณ :)

2
TIL bash มีhelpคำสั่งในตัว
nibot

ซึ่งฉันสามารถ upvote สองครั้งสำหรับการสอนไม่เพียง แต่คำตอบ แต่กระบวนการเช่นกัน
dmckee --- ผู้ดูแลอดีตลูกแมว

@Muu, @nibot, @dmckee: ยังtype type, type help, help typeและhelp helpอาจจะสนุกกับการทำงาน :)
enzotib

10

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


2

มันเป็นคำสั่ง shell builtin: man bash(จากนั้นค้นหา 'ผู้โทร')
มันสามารถใช้เพื่อพิมพ์การติดตามสแต็ก


ขอบคุณแม้ว่าฉันเลือกคำตอบของ enzotib ในขณะที่เขายังสอนฉัน 'ประเภท' ขอบคุณมาก :)

0

โปรดทราบว่าคุณสามารถ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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.