The parentheses are shell syntax.
To reflect syntax which is stored in variable back into the shell for processing, you must use the eval
command.
Merely interpolating the value of the variable into a command line doesn't trigger eval
evaluation of the syntax. That would be an unwanted intrusion of eval, which would cause all sorts of problems.
For instance, consider this:
arg="(parenthesized)"
somecommand $arg
We just want somecommand
to be invoked with the character string (parenthesized)
as its argument; we don't want to run a subshell. That sort of implicit eval would turn harmless data into live code, creating a security hole, not to mention a coding nightmare to try to avoid it.
The rules for how $arg
is treated are independent of position; the expansion happens the same way even if $arg
is the first element in the command line:
$arg foo
Parameter substitution turns $arg
into the text (parenthesized)
and then that is tried as a command, not as a shell syntax.
To execute the piece of shell script stored in input
, use:
eval "$input"
You could also do it like this:
input="echo 1" # no parentheses
/bin/sh -c "$input" # run in subshell explicitly
Of course, the subshell approach feeds the code fragment to the same shell which is executing the surrounding script, whereas here we chose the /bin/sh
which could be different from the invoking shell, or have a different behavior even if it is a symlink to the same shell.