I'm trying to evaluate multiple lines of shell commands using eval
, but when I try to resolve variables with eval separated by a newline \n
the variables are not resolved.
x='echo a'
y='echo b'
z="$x\n$y"
eval $x
eval $y
eval $z
Which outputs:
a
b
anecho b
The last command gives anecho b
, and apparently \n
was treated as n
there. So is there a way to evaluate multiple lines of commands (say, separated by \n
)?
\n
is not a newline; it's an escape sequence that in some situations will be translated into a newline, but you haven't used it in one of those situations. The variable $z
doesn't wind up containing a newline, just backslash followed by "n". As a result, this is what's actually being executed:
$ echo a\necho b
anecho b
You can either use a semicolon instead (which requires no translation), or use \n
in a context where it will be translated into a newline:
$ newline=$'\n'
$ x='echo a'
$ y='echo b'
$ z="$x$newline$y"
$ eval "$z"
a
b
Note the double-quotes around "$z"
-- they're actually critical here. Without them, bash will word-split the value of $z
, turning all whitespace (spaces, tabs, newlines) into word breaks. If that happens, eval
will receive the words "echo" "a" "echo" b", effectively turning the newline into a space:
$ eval $z
a echo b
This is yet another in the long list of cases where it's important to double-quote variable references.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With