评估字符串中的变量

时间:2013-08-13 21:08:38

标签: bash

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

myfile="afile.txt"
mycmd='cat $myfile'
eval $mycmd
echo eval $mycmd

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

4 个答案:

答案 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[@]}"