在Bash中,有没有办法用双引号扩展变量两次?

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:我只是设置了一些东西"我认为这样做是因为双引号只扩展了一次内部的变量.

是否有一种语法上干净的方法在同一行中扩展变量两次?

Cha*_*ffy 8

处理运行时数据时,无法安全地评估两次扩展.

有办法进行重新评估,但它们需要信任您的数据 - 在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.