如何在bash中分隔传递给eval的多个命令

Yih*_*Xie 9 bash shell eval

我正在尝试使用for评估多行shell命令eval,但是当我尝试解析eval用换行符分隔\n的变量时,变量不会被解析.

x='echo a'
y='echo b'
z="$x\n$y"
eval $x
eval $y
eval $z
Run Code Online (Sandbox Code Playgroud)

哪个输出:

a
b
anecho b
Run Code Online (Sandbox Code Playgroud)

最后一个命令给出了anecho b,显然\n被视为n那里.那么有没有办法评估多行命令(比方说,分隔\n)?

Gor*_*son 8

\n不是换行符; 它是一个转义序列,在某些情况下会转换为换行符,但你没有在其中一种情况下使用它.该变量$z不会包含换行符,只有反斜杠后跟"n".结果,这就是实际执行的内容:

$ echo a\necho b
anecho b
Run Code Online (Sandbox Code Playgroud)

您可以使用分号代替(不需要翻译),也可以\n其转换为换行符的上下文中使用:

$ newline=$'\n'
$ x='echo a'
$ y='echo b'
$ z="$x$newline$y"
$ eval "$z"
a
b
Run Code Online (Sandbox Code Playgroud)

请注意双引号"$z"- 它们在这里实际上是关键的.如果没有它们,bash会对$z所有空格(空格,制表符,换行符)进行单词拆分.如果发生这种情况,eval将收到"echo""a""echo"b",有效地将换行符转换为空格:

$ eval $z
a echo b
Run Code Online (Sandbox Code Playgroud)

这是在长引号列表中的另一个例子,其中重要的是引用变量引用.


Eri*_*ski 5

您正在将换行符传递给eval.所以就像你在控制台上打字一样:

el@voyager$ echo a\necho b
anecho b
Run Code Online (Sandbox Code Playgroud)

所以第一个echo被正确理解,它认为你想要引用其余的.反斜杠似乎被忽略了.也许你的意思是这样的:

el@voyager$ echo -e 'a\n'; echo b
a

b
Run Code Online (Sandbox Code Playgroud)

选项1:

使用分号传递到eval的分隔语句,如下所示:

x='echo a'
y='echo b'
z="$x;$y"
eval $x
eval $y
eval $z
Run Code Online (Sandbox Code Playgroud)

打印:

a
b
a
b
Run Code Online (Sandbox Code Playgroud)

选项2:

将换行符放在echo所解释的位置,如下所示:

x='echo -e "a\n"'
y='echo b'
z="$x;$y"
eval $x
eval $y
eval $z
Run Code Online (Sandbox Code Playgroud)

打印:

a

b
a

b
Run Code Online (Sandbox Code Playgroud)

现在换行由echo保留并解释,而不是eval.