1 shell scripting bash command-substitution
当我在终端中执行以下操作时:
x=1
a=($x)
echo $a #output: 1
echo ($x) #output: -bash: syntax error near unexpected token `$x'
Run Code Online (Sandbox Code Playgroud)
为什么上面的输出不同?还有为什么以下 2 个输出不同:
$(echo foo) #output: -bash: foo: command not found
(echo foo) #output: foo
Run Code Online (Sandbox Code Playgroud)
PS:我正在尝试理解命令替换:$(command)
您在 Bash 中混合了三种不同的括号用法:数组定义、命令替换和命令分组。命令替换和命令分组是标准语法,所有类似 POSIXsh的 shell 都支持它们。在额外具有数组的 shell 中支持数组定义语法。
数组被分配给使用形式的复合分配
name=(value1 value2 … )
您a=($x)创建一个具有单个元素的数组,其值是由 指定的值$x,即1。当您按名称回显数组时,在您的情况下echo $a,它只回显数组的第一个元素。这就是你看到的, a1被打印到标准输出。
如果数组中有多个元素,则可以使用"${arrayname[*]}"或"${arrayname[@]}"访问它们。第一个将所有数组元素组合成一个参数,而第二个将每个元素作为一个单独的参数。
此语法特定于bash允许以类似方式使用数组的其他 shell。
命令替换允许命令的输出替换命令本身。当一个命令被如下包围时,会发生命令替换:
$(command)
您的命令$(echo foo)执行 shell 替换并被解析为foo. 所以它和你输入的一样foo。由于该命令foo不存在,bash 会抱怨它。
Bash 提供了两种方法来将要作为一个单元执行的命令列表进行分组。当命令被分组时,重定向可以应用于整个命令列表。例如,列表中所有命令的输出可能被重定向到单个流。
( list )将命令列表放在括号之间会导致创建子 shell 环境(请参阅命令执行环境),并且列表中的每个命令都将在该子 shell 中执行。由于列表是在子shell 中执行的,因此子shell 完成后变量赋值不再有效。
您的命令在子 shell 中(echo foo)执行echo foo,因此foo被回显。这与命令替换无关。正如手册所说,子shell中的变量赋值在子shell完成后不再有效。如果您想编写简单的单行代码,这会派上用场。例如,代替
for l in {1..10}; do mycommand "$l"; done; unset l
Run Code Online (Sandbox Code Playgroud)
你可以写,
( for l in {1..10}; do mycommand "$l"; done )
Run Code Online (Sandbox Code Playgroud)
子shell的另一个有用的用法是使用
( cd folder; ./mycommand )
Run Code Online (Sandbox Code Playgroud)
代替
cd folder; ./mycommand; cd -
Run Code Online (Sandbox Code Playgroud)
您的命令不echo ($x)属于这三个类别,并bash报告语法错误。
还值得一提的是,您应该在适用时引用变量扩展(例如,当字符串应包含变量的值时)。请参阅何时需要双引号?详情。
例如,以下不会调用上述特定构造:
x=1
a="($x)"
echo "$a"
echo "($x)"
Run Code Online (Sandbox Code Playgroud)
在这里,两个调用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
| 归档时间: |
|
| 查看次数: |
2001 次 |
| 最近记录: |