在 Bash 中编写脚本时,我们学会了将变量分配给命令的输出,我们可以使用以下结构:
variable=$(command-string)
这称为命令替换,并在子 shell 环境中执行命令字符串的内容。
我可能发现了异常。
当执行这种形式的命令替换时,如果没有变量赋值,结果会有所不同。
例子:
cmd=date
var=$(echo $cmd)
echo $var
$(echo $cmd)
输出:
date
Fri Jun 29 15:11:58 EDT 2018
没有变量赋值的命令替换似乎正在尝试对命令执行的标准输出进行评估,而变量赋值则不会。
答案1
您的命令替换的计算结果为:date
由于您没有将其分配给任何内容,因此您所做的基本上只是date
在命令提示符下键入。
$ set -x
$ cmd=date
+ cmd=date
$ var=$(echo $cmd)
++ echo date
+ var=date
$ echo $var
+ echo date
date
$ $(echo $cmd)
++ echo date
+ date
Fri Jun 29 13:26:55 MDT 2018
由于date
是有效命令,因此它会按预期执行。
答案2
我相信我已经提出了一个合理的、有些简洁的技术解释。我们正在处理 CLI(命令行解释器),命令替换的结果取决于解析器遇到替换标记“$(”时的解释阶段。
cmd="date"
简单的作业;变量“cmd”具有字符串“date”。
var=$(echo $cmd)
$(echo $cmd)
在第一种情况下,解析器(从左到右读取)遇到了一个标记“=”,因此它知道它正在等待变量赋值的等价字符串。在第二种情况下,当解析器点击“$(”时,解析器尚未确定它正在处理的命令类型。在这两种情况下,解析都会暂停并创建子 shell 环境。括号之间的字符串由 CLI 解释stdout 的内容用于替换“$(”、相应的、不带引号的右括号及其之间的所有内容。现在,CLI 将从中断处继续。在此示例中,在这两个实例中,stdout 均包含字符串“date”在第一个实例中,CLI 需要等效字符串,因此它将“var=date”解释为将字符串“date”分配给变量“var”。在第二个实例中,CLI 将“date”解释为。当前路径中的有效程序,则调用该程序,因此,实际上没有任何问题,这只是解释器执行替换的方式。