2

I am writing a script, and one part of it is not working as I would expect.

I have broken out this part in a simple example for simplicity:

echo 'echo "" > tmp' | while read cmd; do  $cmd ; done

Here I would expect the full command, "echo "" > tmp" to be executed by $cmd.

But this happens:

"" > tmp

The command executed echoes out "" > tmp literally. Instead of echoing out "" and redirecting it to the file tmp. Obviously something is wrong when storing the command in $cmd and then later trying to execute it.

The result is the same even if I simplify it further:

cmd="echo "" > tmp"
$cmd
> tmp

I have tried to experiment with different usages of '' and "", but not solved it yet.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Johnathan
  • 737
  • 2
  • 7
  • 21

2 Answers2

3

Use eval to execute the command stored in the variable:

echo 'echo "" > tmp' | while read cmd; do eval "$cmd" ; done

The value of cmd will be echo "" > tmp. Then when Bash resolves the parameter substitution as a command, the part "" > tmp will be the string arguments of echo, not be recognized as >(redirection). So it will just output the arguments part.

The same as: $(echo 'echo "" > tmp')

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
zhenguoli
  • 2,268
  • 1
  • 14
  • 31
  • 2
    Warning: `eval` has a well-deserved reputation as a bug magnet. It tends to work great when you test it, but cause occasional bizarre results when you run it on real data. And in my experience, if `eval` looks like the answer, it usually means you're asking the wrong question and really should back up and look for a different approach to the underlying problem you're trying to solve. – Gordon Davisson Jun 25 '17 at 19:51
  • @GordonDavisson Just for clarity: could you provide an alternative solution, then? Thanks. – Almir Campos Jul 21 '20 at 20:02
  • @AlmirCampos It depends on the larger situation. You have to look at why you're trying to run a command stored in a variable, and whether there's a better way to solve the larger problem (usually there is). If not, are there parts of the command that might contain dangerous/misparsable shell syntax, and do you have a way to quote/escape them to avoid problems? – Gordon Davisson Jul 21 '20 at 22:17
2

Change

do  $cmd ;

to

do  eval  "$cmd" ;
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
sjsam
  • 21,411
  • 5
  • 55
  • 102
  • 3
    See my comment under zhenguoli's answer. Also, if you must use `eval`, at least double-quote the variable to avoid some *really* bizarre bugs. – Gordon Davisson Jun 25 '17 at 19:53
  • @GordonDavisson Point noted..Yes double quoting to prevent word splitting mainly here... – sjsam Jun 25 '17 at 19:55