我正在尝试使用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)?
\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)
这是在长引号列表中的另一个例子,其中重要的是引用变量引用.
您正在将换行符传递给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.