linux - 在 Bash 中,有没有办法用双引号将变量展开两次?

标签 linux bash parameter-passing variable-expansion parameter-expansion

为了调试我的脚本,我想在每个输出的开头添加内部变量 $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/

相关文章:

linux - awk 并行运行吗?

bash - 在shell中,如何从完整的文件路径中提取子字符串

java - Java 是 "pass-by-reference"还是 "pass-by-value"?

c++ - 异步的令人费解的行为

从文件名计算字数统计程序中的字数

linux - 如何在没有扩展名的情况下运行linux命令

python - 如何在使用 paramiko 模块在 python 脚本中建立 ssh 连接时保护密码?

Bash 逐行读取文本文件并触发 logger 将该行记录到 var/log

python - Python 方法如何处理任意参数?

objective-c - 修改 iOS 中的 BOOL 内部方法