是否可以使用shell脚本打印变量内容的内容?(间接引用)

Raf*_*rsk 13 bash shell-script echo variable-substitution variable

假设我已经声明了以下变量:

$ var='$test'
$ test="my string"
Run Code Online (Sandbox Code Playgroud)

如果我打印它们的内容,我会看到以下内容:

$ echo $var
$test

$ echo $test
my string
Run Code Online (Sandbox Code Playgroud)

我想找到一种方法来打印内容的内容$var(即 的内容$test)。所以我尝试执行以下操作:

$ echo $(echo $var)
$test
Run Code Online (Sandbox Code Playgroud)

但这里的结果是$test而不是"my string"......是否可以使用bash打印变量内容的内容?

jes*_*e_b 22

您可以使用 bash 的间接变量扩展来完成此操作(只要您可以$从参考变量中删除):

$ var=test
$ test="my string"
$ echo "$var"
test
$ echo "${!var}"
my string
Run Code Online (Sandbox Code Playgroud)

3.5.3 Shell 参数扩展


Dan*_*ver 11

对于包含在中的变量名称var$您为前缀的情况,可以使用eval

$ var='$test'
$ test="my string"
$ eval echo $var
my string
Run Code Online (Sandbox Code Playgroud)

这里发生了什么:

  • bash 扩展$var到 value $test,产生一个eval echo $test命令;
  • eval计算echo $test表达式并产生所需的结果。

请注意,eval通常使用可能是危险的(取决于存储在 中的内容var),因此最好避免使用它。间接扩展功能更适合您的情况(但您需要摆脱$登录$test)。

  • 我总是推荐双引号变量引用(以避免意外分词和通配符扩展带来的麻烦)。使用`eval`,你需要两层双引号,行:`eval echo "\"$var\""`。请注意,这与您提到的使用“eval”的其他危险没有任何关系。 (5认同)

Kus*_*nda 9

类似于Jesse_b's answer,但使用名称引用变量而不是变量间接(需要bash4.3+):

$ declare -n var=test
$ test="my string"
$ echo "$var"
my string
Run Code Online (Sandbox Code Playgroud)

name 引用变量var保存它引用的变量的名称。当该变量被取消引用为 时$var,将返回该其他变量的值。

bash 递归解析名称引用:

$ declare -n var1=var2
$ declare -n var2=test
$ test="hello world"
$ echo "$var1"
hello world
Run Code Online (Sandbox Code Playgroud)

为了完整bash起见,使用关联数组(在4.0+ 中)也是解决此问题的一种方法,具体取决于要求:

$ declare -A strings
$ strings[test]="my string"
$ var=test
$ echo "${strings[$var]}"
my string
Run Code Online (Sandbox Code Playgroud)

这提供了一种通过可动态确定的键或名称访问多个值的更灵活的方式。如果您想在单个数组中收集特定类别的所有值,但仍然能够通过某些键(例如,可通过 ID 访问的名称,或可通过目的访问的路径名等)访问它们,这可能更可取,因为它不会污染脚本的变量命名空间。