评估字符串中的变量

Rob*_*ick 13 bash

此脚本中的最后一行将无法正常工作:

myfile="afile.txt"
mycmd='cat $myfile'
eval $mycmd
echo eval $mycmd
Run Code Online (Sandbox Code Playgroud)

这里echo打印'eval cat $ myfile'.如何打印'eval cat afile.txt'?

Dav*_* W. 36

让我们一步一步来:

当你这样做:

mycmd='cat $myfile'
Run Code Online (Sandbox Code Playgroud)

您可以阻止shell进行插值$myfile.从而:

$ echo $mycmd
cat $myfile
Run Code Online (Sandbox Code Playgroud)

如果要允许插值,可以使用双引号:

$ mycmd="echo $myfile"  #Double quotes!
$ echo "$mycmd"
cat afile.txt
Run Code Online (Sandbox Code Playgroud)

当然,这会冻结$mycmd你做什么时的解释eval.

$ myfile="afile.txt"
$ mycmd="echo $myfile"
$ echo $mycmd
cat afile.txt
$ eval $mycmd   #Prints out afile.txt
$ myfile=bfile.txt
$ eval $mycmd   #Still prints out afile.txt and not bfile.txt
Run Code Online (Sandbox Code Playgroud)

比较这个:

$ myfile="afile.txt"
$ mycmd='cat $myfile'   #Single quotes hide $myfile from the shell
echo $mycmd
cat $myfile             #Shell didn't change "$myfile", so it prints as a literal
$ eval $mycmd           #Prints out afile.txt
$ myfile=bfile.txt
$ eval $mycmd           #Now prints out bfile.txt
Run Code Online (Sandbox Code Playgroud)

您可能想要做的是$mycmd在回显时评估echo语句:

$ echo $(eval "echo $mycmd")
$ cat afile.txt
$ myfile=bfile.txt
$ echo $(eval "echo $mycmd")
cat bfile.txt
Run Code Online (Sandbox Code Playgroud)


rua*_*akh 9

你可以写:

eval echo eval $mycmd
Run Code Online (Sandbox Code Playgroud)

或者更健壮一点:

eval echo eval "$mycmd"
Run Code Online (Sandbox Code Playgroud)

也就是说,我建议eval尽可能避免; 它往往非常脆弱,因为Bash命令行处理中有许多复杂的步骤,并且eval通常意味着您将多次执行这些步骤.很难跟踪真实情况.