yegor256
yegor256

Reputation: 105053

How to build bash command from variable?

I have a bash variable:

A="test; ls"

I want to use it as part of a call:

echo $A

I'm expecting it to be expanded into:

echo test; ls

However, it is expanded:

echo "test;" "ls"

How is it possible to achieve what I want? The only solution I can think of is this:

bash -c "echo $A"

Maybe there is something more elegant?

Upvotes: 0

Views: 84

Answers (2)

Charles Duffy
Charles Duffy

Reputation: 295298

If you're building compound commands, running redirections, etc., then you need to use eval:

A="test; ls"
eval "$A"

However, it's far better not to do this. A typical use case that follows good practices follows:

my_cmd=( something --some-arg "another argument with spaces" )
if [[ $foo ]]; then
  my_cmd+=( --foo="$foo" )
fi
"${my_cmd[@]}"

Unlike the eval version, this can only run a single command line, and will run it exactly as-given -- meaning that even if foo='$(rm -rf /)' you won't get your hard drive wiped. :)


If you absolutely must use eval, or are forming a shell command to be used in a context where it will necessarily be shell-evaluated (for instance, passed on a ssh command line), you can achieve a hybrid approach using printf %q to form command lines safe for eval:

printf -v cmd_str 'ls -l %q; exit 1' "some potentially malicious string"
eval "$cmd_str"

See BashFAQ #48 for more details on the eval command and why it should be used only with great care, or BashFAQ #50 for a general discussion of pitfalls and best practices around programmatically constructing commands. (Note that bash -c "$cmd_str" is equivalent to eval in terms of security impact, and requires the same precautions to use safely).

Upvotes: 3

bring1234y
bring1234y

Reputation: 1

dont use echo, just have the var

A="echo test; ls"

$A

Upvotes: -1

Related Questions