How to run string with values as a command in bash?
Here is my small bash script snippet.
i=5
command='echo $i'
$command
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?
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")
"${command[@]}"
That would run echo
, with echo
, $i
and the content of $i
as arguments.
command='echo $i ;x /* '$i
$command
(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.