为了调试我的脚本,我想在每个输出的开头添加内部变量 $FUNCNAME 和 $LINENO,这样我就知道输出发生在哪个函数和行号上。
foo(){
local bar="something"
echo "$FUNCNAME $LINENO: I just set bar to $bar"
}
但是因为会有很多调试输出,所以如果我能做类似下面的事情会更清晰:
foo(){
local trace='$FUNCNAME $LINENO'
local bar="something"
echo "$trace: I just set bar to $bar"
}
但是上面的字面输出: “$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
...当使用 bash 4.4.19(1)-release 运行时,发出:
foo:7: I just set bar to baz
注意 ${BASH_LINENO[0]}
和 ${FUNCNAME[1]}
的使用;这是因为 BASH_LINENO
定义如下:
An array variable whose members are the line numbers in source files where each corresponding member of FUNCNAME was invoked.
因此,FUNCNAME[0]
是 trace
,而 FUNCNAME[1]
是 foo
;而 BASH_LINENO[0]
是调用 trace
的那一行——函数 foo
中的一行。
关于linux - 在 Bash 中,有没有办法用双引号将变量展开两次?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50537090/