什么是“呼叫者”命令?

什么是“呼叫者”命令?

我正在运行 Ubuntu 10.10,上面运行着 openbox。我今天注意到一个名为 的命令caller,但是没有手册页,它不响应任何输入(或 --help),并且 whereis 找不到它。

知道它是什么吗?

答案1

跑步

type caller

你会看到它是一个内置的 shell。跑步

help caller

将显示其功能,并在 bash 的手册页中报告。简要地

Return the context of the current subroutine call.

答案2

iscaller内置命令(POSIX 未指定)出现在 Bash 3.0 版本中,它返回任何活动子例程调用的上下文。看:Bash 内置以便更多阅读。

句法:

caller [FRAMENUMBER]

如果帧数作为非负整数提供,它显示当前执行调用堆栈中与该位置相对应的行号、子例程名称和源文件。

没有任何参数,呼叫者显示当前子程序调用的行号和源文件名。

检查以下内容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})。工具如巴什数据库可以帮助使用 Bash 的一些更高级的调试功能。

答案3

请注意,您可以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

答案4

这是一个 shell 内置命令:(man bash然后搜索“caller”)
它可用于打印堆栈跟踪。

相关内容