此脚本中的最后一行无法正常工作:
myfile="afile.txt"
mycmd='cat $myfile'
eval $mycmd
echo eval $mycmd
这里echo print'eval cat $ myfile'。如何打印'eval cat afile.txt'?
答案 0 :(得分:32)
让我们一步一步走:
执行此操作时:
mycmd='cat $myfile'
您可以阻止shell插入$myfile
。因此:
$ echo $mycmd
cat $myfile
如果要允许插值,可以使用双引号:
$ mycmd="echo $myfile" #Double quotes!
$ echo "$mycmd"
cat afile.txt
当然,当您执行$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
将其与:
进行比较$ 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
您可能想要做的是在回显时评估echo语句中的$mycmd
:
$ echo $(eval "echo $mycmd")
$ cat afile.txt
$ myfile=bfile.txt
$ echo $(eval "echo $mycmd")
cat bfile.txt
答案 1 :(得分:9)
你可以写:
eval echo eval $mycmd
或者更健壮一点:
eval echo eval "$mycmd"
那就是说,我建议尽可能避免eval
;它往往非常脆弱,因为Bash命令行处理中有许多复杂的步骤,使用eval
通常意味着您将多次执行这些步骤。很难跟踪真实情况。
答案 2 :(得分:1)
你需要评估回声,而不是相反:
eval echo "eval $mycmd"
或
eval echo eval "$mycmd"
我认为前者更可取,但至少引用变量扩展。
答案 3 :(得分:1)
如果您正在使用bash,更好的方法是使用数组:
myfile="afile.txt"
mycmd=(cat "$myfile")
echo "${mycmd[@]}"
"${mycmd[@]}"