2

How can I get the stored command to work for the following scenario:

CMD='echo "test" >> test.txt'
$CMD

It will work for other scenarios like:

CMD='mkdir test'
$CMD
  • 1
    I believe you are running into the difference between word splitting (after variable expansion) and the way bash handles redirection, which it does before variable expansion. So running just $CMD here operates the same as if you ran echo "test" '>>' test.txt. As one answerer posted already, eval $CMD is a workaround. – Wildcard Dec 8 '15 at 18:36
6

The correct rule must be:

  • Store data in variables, Store code in functions.

So, the correct way to have that command working is: make a function:

first_command (){ echo "test" >> test.txt; }

Call the function:

first_command

That's it.


It is wrong to store a command as an string.
It is even worse to use eval to run such commands.

It may seem to work for the simple command, but the hidden problem is that the eval step removes the quoting of the command.

If you store this command

CMD='echo "test" >> test.txt'

The eval "$CMD" (yes, even quoted) will execute this command:

echo test >> test.txt

No quotes !!!.

It is very easy to forget that quotes need special management with eval. And making quotes working correctly is always tricky anyway.

Trying to execute a command stored in a variable which does not have re-directions (the main problem which demand the use of eval) without the eval step is still tricky, and doesn't work in all cases.

Please read an excellent introduction to the problem here:
I'm trying to put a command in a variable, but the complex cases always fail!

  • CMD='echo "test test" >>test.txt' <there are supposed to be a lot of spaces over there. dangit! it is easy to forget, though. eval "$var" = sh -c "$var" if you put exactly the stuff in the former as you would in the latter it will probably work out. thats my rule of thumb, anyway. have an upvote. – mikeserv Dec 8 '15 at 20:08
  • I was using the scenario of passing a command in a function to run it and if it is unsuccessful, it would do an action. I have changed it to "command 2>> error.log || handleCMDError" – Shayne Manning Dec 8 '15 at 21:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.