How to run string with values as a command in bash?

Here is my small bash script snippet.

command='echo $i'

I want this script to print 5 i.e., I want it to run echo and print 5. But it instead keeps printing $i. So how do I go about solving this?

Asked By: posixKing


That would be:

eval "$command"

If you want the content of $command to be evaluated as shell code.

If you can’t guarantee that $command won’t start with - (which would cause eval in some shells like bash to treat it as an option), you may want to run:

eval " $command"

instead. That extra leading space won’t affect the way the command is parsed and will prevent $command from being treated as an option to eval if it starts with -. eval -- "$command" would also work in some shells (including bash) but is not POSIX (IIRC) and wouldn’t work in dash or the Bourne shell for instance.

Note that your $command should probably be:

command='echo "$i"'

Unless you did intend $i to be subject to split+glob

A potentially better way to store code in "variables" would be to use functions:

mycommand() { echo "$i"; }

(using mycommand instead of command, as command is already an existing command).

If $command is break/continue/return, behaviour will vary depending on the shell.

If you wanted $command to store a simple command, that is a list of words the first of which is looked up as the command to execute with the list of words as arguments, you’d use an array variable:

command=('echo' '$i' "$i")

That would run echo, with echo, $i and the content of $i as arguments.

command='echo $i ;x /* '$i

(with the default value of $IFS) is the one that would make littlest sense. There, $command would contain a string. The first $i left as is, the second expanded (as outside the single quotes), and then that string would be subject to split+glob (as $command is not inside double quotes), the outcome of which would result in a number of words, taken as a simple command again.

Answered By: Stéphane Chazelas
Categories: Answers Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.