It seems command subsitution take the first token as the command, remainings as the arguments of command, not parsed as shell statement. but the bash manual says that :
Bash performs the expansion by executing command in a subshell environment
example
$ c="echo 123 ; echo 124"
$ d=`$c`
$ echo $d
123 ; echo 124
why d is 13 ; echo 124
not 123 124
This happens because in d=`$c`
, the command is not echo 123 ; echo 124
but instead $c
.
This means that Bash follows the evaluation steps for so-called simple commands, described in detail in POSIX.
Skipping over irrelevant parts, the steps involved are:
- The words that are not variable assignments or redirections shall be expanded. If any fields remain following their expansion, the first field shall be considered the command name and remaining fields are the arguments for the command.
So $c
is expanded according to the rules:
Tilde expansion (see Tilde Expansion), parameter expansion (see Parameter Expansion), command substitution (see Command Substitution), and arithmetic expansion (see Arithmetic Expansion) shall be performed, beginning to end. See item 5 in Token Recognition.
$c
turns into echo 123 ; echo 124
Field splitting (see Field Splitting) shall be performed on the portions of the fields generated by step 1, unless IFS is null.
echo 123 ; echo 124
turns into echo
, 123
, ;
, echo
, 124
If there is a command name, execution shall continue as described in Command Search and Execution .
echo
is invoked with the arguments 123
, ;
, echo
, 124
, and prints them out.
For it to work the way you expected, there would have to be a step "after expansion, take the resulting string and parse it again according to the shell grammar rules", but there isn't.
Good thing too, because imagine if read -p "Name: " name;
would let you enter "; rm -rf /; "
and turn echo "Hello $name"
into echo "Hello "; rm -rf /; ""