0

The following code when run as an individual command in shell script gives the expected result :

for x in This is good; do echo $x; done

[OUTPUT]

This
is
good

However when i pass it inside a string to Eval for some reason x is not being initialised

cmd = " for x in This is good; do echo $x ; done"
eval $cmd

[OUTPUT]

//Three blank lines

Why is x not being initialised ?

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
kurokami
  • 1
  • 1
  • 1
    BTW, note that using `eval` in bash is generally a "code smell". It [introduces security vulnerabilities](http://mywiki.wooledge.org/BashFAQ/048) when not used very carefully, and new versions of the language provide ways to accomplish most or all of its typical use cases [without needing it](https://mywiki.wooledge.org/BashFAQ/006). – Charles Duffy Aug 24 '21 at 15:25
  • Also, `cmd = "some string"` isn't actually an assignment in bash -- it tries to run `cmd` with the first argument `=` and the second argument `some string`; to have an assignment proper, one cannot have spaces around the `=`. – Charles Duffy Aug 24 '21 at 15:27

1 Answers1

0

Use single quotes to assign to cmd so $x isn't already consumed at assignment time.

Also, put double quotes around your argument to eval (the bugs it prevents are more subtle, and don't impact your current string, but when you do hit them they're serious).

cmd='for x in This is good; do echo "$x"; done'
eval "$cmd"

Note echo "$x" instead of echo $x -- see I just assigned a variable, but echo $variable shows something different!

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
  • Is there a way to keep cmd in double quotes and still have it working as expected ? – kurokami Aug 24 '21 at 15:38
  • @kurokami, `"\$x"` -- adding a backslash before the `$` -- will work. – Charles Duffy Aug 24 '21 at 15:42
  • @kurokami, also, note that you can change quoting types within a string, so you can have most of the string in double quotes, but then just that one part in single quotes. – Charles Duffy Aug 24 '21 at 15:42
  • 1
    @kurokami, ...however, that gets complex quickly, which is part of why storing code in strings is an antipattern; the good-practice way to store code is in functions, which the shell itself can come up with a correctly-escaped textual representation of if you need to pass them around. – Charles Duffy Aug 24 '21 at 15:43