echo ($x) 和 a="($x)" 之间的区别;回显$a

echo ($x) 和 a="($x)" 之间的区别;回显$a

当我在终端中执行以下命令时:

x=1
a=($x)

echo $a    #output: 1
echo ($x)  #output: -bash: syntax error near unexpected token `$x'

为什么上面的输出不同?另外为什么以下两个输出不同:

$(echo foo) #output: -bash: foo: command not found
(echo foo) #output: foo

PS:我试图理解命令替换:$(command)

答案1

您在 Bash 中混合了括号的三种不同用法:数组定义、命令替换和命令分组。命令替换和命令分组是标准语法,所有类似 POSIXsh的 shell 都支持它们。另外具有数组的 shell 支持数组定义语法。

数组定义

数组使用以下形式的复合赋值进行赋值

name=(value1 value2 … )

您创建一个包含单个元素的数组,其值是, iea=($x)指定的值。当您按名称回显数组时,在您的情况下,它仅回显数组的第一个元素。这就是您所看到的,a被打印到标准输出。$x1echo $a1

如果数组中有多个元素,则可以使用"${arrayname[*]}""${arrayname[@]}"来访问它们。第一个将所有数组元素组合成一个参数,而第二个将每个元素作为单独的参数。

此语法特定于bash其他允许以类似方式使用数组的 shell。

命令替换 (POSIX)

命令替换允许命令的输出替换命令本身。当命令被如下括起来时,就会发生命令替换:

$(command)

您的命令$(echo foo)执行 shell 替换并解析为foo.所以它与您输入的内容相同foo。由于该命令foo不存在,bash 会抱怨它。

命令分组 (POSIX)

Bash 提供了两种方法将要执行的命令列表分组为一个单元。当命令被分组时,重定向可以应用于整个命令列表。例如,列表中所有命令的输出可以被重定向到单个流。

( list )

将命令列表放在括号之间会导致创建子 shell 环境(请参阅命令执行环境),并且列表中的每个命令都会在该子 shell 中执行。由于列表是在子 shell 中执行的,因此在子 shell 完成后变量分配不会保持有效。

您的命令在子 shell 中(echo foo)执行,因此会得到回显。这与命令替换无关。正如手册所说,子 shell 完成后,子 shell 中的变量分配不会保持有效。如果您想写简单的单行文字,这会很方便。例如,代替echo foofoo

for l in {1..10}; do mycommand "$l"; done; unset l

你可以写,

( for l in {1..10}; do mycommand "$l"; done )

子 shell 的另一个有用用法是使用

( cd folder; ./mycommand )

代替

cd folder; ./mycommand; cd -

您的命令echo ($x)不属于这三个类别中的任何一个,并且bash报告语法错误。

正确引用你的变量

还值得一提的是,只要适用,您就应该引用变量扩展(例如,当字符串应包含变量的值时)。看什么时候需要双引号?了解详情。

例如,以下内容不会调用上述特定构造:

x=1
a="($x)"

echo "$a"
echo "($x)"

在这里,两个调用echo都会输出(1).

bash手册页链接

https://www.gnu.org/software/bash/manual/html_node/Command-Grouping.html

https://www.gnu.org/software/bash/manual/html_node/Command-Substitution.html

https://www.gnu.org/software/bash/manual/html_node/Arrays.html

相关内容