bash 评估字符串中的变量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18219262/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 00:04:00  来源:igfitidea点击:

Evaluating variables in a string

bash

提问by Robert Kubrick

The last line in this script won't work as I expect:

此脚本中的最后一行不会按我的预期工作:

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

Here echo prints 'eval cat $myfile'. How can I print 'eval cat afile.txt'?

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

回答by David W.

Let's take things step by step:

让我们一步一步来:

When you do this:

当你这样做时:

mycmd='cat $myfile'

You prevent the shell from interpolating $myfile. Thus:

您可以防止 shell 进行插值$myfile。因此:

$ echo $mycmd
cat $myfile

If you want to allow the interpolation, you can use double quotes:

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

$ mycmd="echo $myfile"  #Double quotes!
$ echo "$mycmd"
cat afile.txt

This, of course, freezesthe interpretation of $mycmdwhen you do an eval.

当然,这会冻结$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

Compare this to:

将此与:

$ 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

What you probably want to do is to evaluate the $mycmdin an echo statement when you echo it:

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

$ echo $(eval "echo $mycmd")
$ cat afile.txt
$ myfile=bfile.txt
$ echo $(eval "echo $mycmd")
cat bfile.txt

回答by ruakh

You can write:

你可以写:

eval echo eval $mycmd

or a bit more robust:

或者更健壮一点:

eval echo eval "$mycmd"

That said, I'd recommend avoiding evalwhenever possible; it tends to be very fragile, because there are many complicated steps in Bash command-line processing, and use of evaltypically means you will perform those steps more than once. It's hard to keep track of what's really going on.

也就是说,我建议eval尽可能避免;它往往非常脆弱,因为 Bash 命令行处理中有许多复杂的步骤,而使用eval通常意味着您将多次执行这些步骤。很难跟踪到底发生了什么。

回答by seanmcl

You need to eval the echo, rather than the other way around:

您需要评估回声,而不是相反:

eval echo "eval $mycmd"

or

或者

eval echo eval "$mycmd"

I think the former is preferable, but at least quote the variable expansion.

我认为前者更可取,但至少引用变量扩展。

回答by konsolebox

If you're using bash, the better way to do it is to use arrays:

如果您使用 bash,更好的方法是使用数组:

myfile="afile.txt"
mycmd=(cat "$myfile")
echo "${mycmd[@]}"
"${mycmd[@]}"