此脚本中的最后一行将无法正常工作:
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)
你可以写:
eval echo eval $mycmd
Run Code Online (Sandbox Code Playgroud)
或者更健壮一点:
eval echo eval "$mycmd"
Run Code Online (Sandbox Code Playgroud)
也就是说,我建议eval尽可能避免; 它往往非常脆弱,因为Bash命令行处理中有许多复杂的步骤,并且eval通常意味着您将多次执行这些步骤.很难跟踪真实情况.