Bad*_*ten 3 linux bash parameter-passing variable-expansion parameter-expansion
为了调试我的脚本,我想在每个输出的开头添加内部变量$ FUNCNAME和$ LINENO,所以我知道输出发生在哪个函数和行号上.
foo(){
local bar="something"
echo "$FUNCNAME $LINENO: I just set bar to $bar"
}
Run Code Online (Sandbox Code Playgroud)
但是由于会有很多调试输出,如果我可以执行以下操作,它会更清晰:
foo(){
local trace='$FUNCNAME $LINENO'
local bar="something"
echo "$trace: I just set bar to $bar"
}
Run Code Online (Sandbox Code Playgroud)
但上面的字面输出:"$ FUNCNAME $ LINENO:我只是设置了一些东西"我认为这样做是因为双引号只扩展了一次内部的变量.
是否有一种语法上干净的方法在同一行中扩展变量两次?
有办法进行重新评估,但它们需要信任您的数据 - 在NSA系统设计意义上:"可信组件是一个可以在系统失败时破坏系统的组件".
有关详细讨论,请参阅BashFAQ#48.请记住,如果您可以记录文件名,那么除了NUL之外的任何字符都可以出现在UNIX文件名中.$(rm -rf ~)'$(rm -rf ~)'.txt是一个合法的名称.*是一个合法的名称.
#!/usr/bin/env bash
trace() { echo "${FUNCNAME[1]}:${BASH_LINENO[0]}: $*" >&2; }
foo() {
bar=baz
trace "I just set bar to $bar"
}
foo
Run Code Online (Sandbox Code Playgroud)
...当用bash运行时4.4.19(1) - 发布,发出:
foo:7: I just set bar to baz
Run Code Online (Sandbox Code Playgroud)
注意使用${BASH_LINENO[0]}和${FUNCNAME[1]}; 这是因为BASH_LINENO定义如下:
一个数组变量,其成员是源文件中的行号,其中调用了FUNCNAME的每个相应成员.
因此,FUNCNAME[0]是trace的,而FUNCNAME[1]是foo; 而BASH_LINENO[0]是从该行trace被称为-的线是在函数内部foo.