Tom*_*ale 9 shell debugging zsh function
在 bash 中,我可以写:
caller 0
Run Code Online (Sandbox Code Playgroud)
并接收调用者上下文的:
这对于调试非常有用。鉴于:
yelp () { caller 0; }
Run Code Online (Sandbox Code Playgroud)
然后我可以写yelp
来看看到达了哪些代码行。
我可以实现caller 0
在bash
如下:
echo "${BASH_LINENO[0]} ${FUNCNAME[1]} ${BASH_SOURCE[1]"
Run Code Online (Sandbox Code Playgroud)
我怎样才能获得相同的输出caller 0
中zsh
?
mur*_*uru 15
我认为没有等效的内置命令,但是可以使用来自zsh/Parameter 模块的这四个变量的某些组合:
Run Code Online (Sandbox Code Playgroud)funcfiletrace
此数组包含调用当前函数、源文件或(如果
EVAL_LINENO
已设置)eval
命令的点的绝对行号和相应的文件名 。该数组的长度与funcsourcetrace
and相同functrace
,但不同之处在于funcsourcetrace
行和文件是调用点,而不是定义点,不同之处functrace
在于所有值都是文件中的绝对行号,而不是相对于函数的开始,如果有的话。Run Code Online (Sandbox Code Playgroud)funcsourcetrace
此数组包含 定义当前正在执行的函数、源文件和(如果
EVAL_LINENO
已设置)eval
命令的点的文件名和行号。行号是“function name
”或“name ()
”开始的行。在自动加载函数的情况下,行号报告为零。每个元素的格式是filename:lineno
.对于从原生 zsh 格式的文件自动加载的函数,其中只有函数的主体出现在文件中,或者对于已由
source
或 '.
' 内置函数执行的文件,跟踪信息显示为filename:0
,因为整个文件是定义。加载函数时,源文件名被解析为绝对路径,否则解析为它的路径。大多数用户会对
funcfiletrace
数组中的信息感兴趣 。Run Code Online (Sandbox Code Playgroud)funcstack
此数组包含函数、源文件和(如果
EVAL_LINENO
已设置)eval
命令的名称。目前正在执行。第一个元素是使用参数的函数名称。标准 shell 数组
zsh_eval_context
可用于确定在每个深度执行的 shell 构造的类型:但是请注意,这是相反的顺序,最近的项目最后,并且更详细,例如包括一个条目顶层,主要的 shell 代码以交互方式或从脚本执行,它不存在于$funcstack
.Run Code Online (Sandbox Code Playgroud)functrace
该数组包含与当前正在执行的函数对应的调用者的名称和行号。每个元素的格式是
name:lineno
. 还显示了源文件的调用者;调用者是执行source
or '.
' 命令的点。
比较:
foo.bash
:
funcfiletrace
Run Code Online (Sandbox Code Playgroud)
foo.zsh
:
funcsourcetrace
Run Code Online (Sandbox Code Playgroud)
结果:
funcstack
Run Code Online (Sandbox Code Playgroud)
因此,相应的值在${funcfiletrace[1]}
和 中${funcstack[-1]}
。修改yelp
为:
functrace
Run Code Online (Sandbox Code Playgroud)
输出是:
#! /bin/bash
yelp() {
caller 0
}
foo () {
yelp
}
foo
Run Code Online (Sandbox Code Playgroud)
这非常接近 bash 的
#! /bin/zsh
yelp() {
print -l -- $funcfiletrace - $funcsourcetrace - $funcstack - $functrace
}
foo () {
yelp
}
foo
Run Code Online (Sandbox Code Playgroud)