bash 命令替换作为单个命令执行,未解析为 shell 语句
bash command substitution executed as a single command not parsed as shell statement
好像command subsituation是把第一个token作为command,剩下的作为command的参数,
未解析为 shell 语句。但是 bash 手册说:
Bash performs the expansion by executing command in a subshell
environment
例子
$ c="echo 123 ; echo 124"
$ d=`$c`
$ echo $d
123 ; echo 124
为什么 d 是 13 ; echo 124
而不是 123 124
发生这种情况是因为在 d=`$c`
中,命令不是 echo 123 ; echo 124
,而是 $c
。
这意味着 Bash 遵循所谓的简单命令的评估步骤,described in detail in POSIX。
跳过无关部分,涉及的步骤是:
- 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.
所以$c
按照规则展开:
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
变成 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
变为echo
、123
、;
、echo
、124
If there is a command name, execution shall continue as described in Command Search and Execution .
echo
使用参数 123
、;
、echo
、124
调用并打印出来。
为了让它按照你预期的方式工作,必须有一个步骤“展开后,根据 shell 语法规则获取结果字符串并再次解析它”,但没有.
也是好事,因为想象一下如果 read -p "Name: " name;
会让你输入 "; rm -rf /; "
并将 echo "Hello $name"
变成 echo "Hello "; rm -rf /; ""
好像command subsituation是把第一个token作为command,剩下的作为command的参数, 未解析为 shell 语句。但是 bash 手册说:
Bash performs the expansion by executing command in a subshell environment
例子
$ c="echo 123 ; echo 124"
$ d=`$c`
$ echo $d
123 ; echo 124
为什么 d 是 13 ; echo 124
而不是 123 124
发生这种情况是因为在 d=`$c`
中,命令不是 echo 123 ; echo 124
,而是 $c
。
这意味着 Bash 遵循所谓的简单命令的评估步骤,described in detail in POSIX。
跳过无关部分,涉及的步骤是:
- 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.
所以$c
按照规则展开:
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
变成 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
变为echo
、123
、;
、echo
、124
If there is a command name, execution shall continue as described in Command Search and Execution .
echo
使用参数 123
、;
、echo
、124
调用并打印出来。
为了让它按照你预期的方式工作,必须有一个步骤“展开后,根据 shell 语法规则获取结果字符串并再次解析它”,但没有.
也是好事,因为想象一下如果 read -p "Name: " name;
会让你输入 "; rm -rf /; "
并将 echo "Hello $name"
变成 echo "Hello "; rm -rf /; ""