本文旨在总结shell 中各种括号的作用,以及使用场景等。
shell 中常见的括号有以下几种,我会分别讲解各个符号的作用。

() (())[][[]]{}  

1. 首先来介绍 () 以及 (())

命令替换 $()
命令替换就是将shell命令的输出赋给变量,它是脚本编程中的一个主要组成部分。

 $ date
2022年 02月 28日 星期一 15:34:24 CST
 $ test=$(date)
 $ echo $test
2022年 02月 28日 星期一 15:34:34 CST
 $

除了使用$() 进行命令替换以外,还可以用 `` 符号。 注意在美式键盘上,它通常和波浪线( ~)位于同一键位。

$ test2=`date`
 $ echo $test2
2022年 02月 28日 星期一 15:36:50 CST

进程列表 (;;)
进程列表是一种命令分组( command grouping)。另一种命令分组是将命令放入花括号中, 并在命令列表尾部加上分号( ;)。语法为{ command; }。使用花括号进行命令分组并不会像进程列表那样创建出子shell。首先我们来看以下的命令。

 $ (pwd ;ls ;echo  $BASH_SUBSHELL )
/Data2/Team/huangtianbao/learn/source/test
123  tests.c
1
 $ pwd ;ls ;echo  $BASH_SUBSHELL
/Data2/Team/huangtianbao/learn/source/test
123  tests.c
0

通过在每个命令后面加 分号 (😉 可以实现在一行中运行一系列命令,这个方式叫做命令列表。但是同样的命令列表有()括起来的和没括起来的 输出的 $BASH_SUBSHELL 变量不一样。显示的是数字0。这就表明这些命令不是在子shell中运行的。这是因为有()括起来的会生成子shell 来运行命令。括号的加入使命令列表变成了进程列表。

数组变量(a b c d )
在shell 中也是支持定义数组的,数组的赋值是通过()括起来的,数组元素之间通过空格分隔,并且数组的下标是从零开始的。其中和其他编译语言一样要访问数组元素需要通过数组名+[下标]的方式访问。[*] 比较特别,它可以列出数组的所有元素。并且变量名指代的是数组变量的第一个元素也就是[0]。

 $ test=(a b c d)
 $ echo ${test[*]}
 a b c d
 $ echo ${test[0]}
 a
 $ echo $test
 a

复杂运算(())
双括号命令允许你在比较过程中使用高级数学表达式。双括号命令提供了更多的数学符号,这些符号对于用过其他编程语言的程序员而言并不陌生。双括号命令的格式如下:
(( expression ))
expression可以是任意的数学赋值或比较表达式。下表列出了双括号命令中会用到的其他运算符。
双括号复杂数学运算

 $ a=1
 $ ((a++))
 $ echo $a
2
 echo $((a**3))
8

2.然后介绍 [] 以及 [[]]
通配符[]
使用了中括号以及在特定位置上可能出现的两种字符: 1或3。中括号表示一个字符位置并给出多个可能的选择。可以像上面的例子那样将待选的字符列出来,也可以指定字符范围,例如字母范围[1–3]。

$ ls
123  223  323  tests.c
$ ls [13]*
123  323
$ ls [1-3]*
123  223  323

数学运算$[]
一般数学运算可以用,expr 命令但是expr 命令会有缺点,它在处理一些特定字符会出现问题,例如 “ * ”星号符 。在遇到特俗符号时需要使用shell的转义字符(反斜线)将其标出来。

$ expr 1 + 5
6
$ expr 5 * 2
expr: syntax error
$ expr 5 \* 2
10

用方括号执行shell数学运算比用expr命令方便很多。在使用方括号来计算公式时,不用担心shell会误解乘号或其他符号。 shell知道它不是通配符,因为它在方括号内。bash shell数学运算符只支持整数运算。若要进行任何实际的数学计算,这是一个巨大的限制。

$ var1=$[1 + 5]
$ echo $var1
6
$ var2=$[$var1 * 2]
$ echo $var2
12
 $ var1=100
 $ var2=45
 $ var3=$[$var1 / $var2]
 $ echo The final result is $var3
 The final result is 2

**字符串和数值比较 [] **
在bash shell 中 无需在if-then语句中声明test命令。

if  test(可选的)  [ condition ]
then
commands
fi

注意,第一个方括号之后和第二个方括号之前必须加上一个空格,否则就会报错。
test命令可以判断三类条件:
数值比较
字符串比较
文件比较

这部分的内容比价多,有兴趣的可以自行查找资料。

**模式匹配比较 [[]] **
双方括号命令提供了针对字符串比较的高级特性。双方括号命令的格式如下:

[[ expression ]]

双方括号里的expression使用了test命令中采用的标准字符串比较。但它提供了test命
令未提供的另一个特性——模式匹配( pattern matching)。双方括号在bash shell中工作良好。不过要小心,不是所有的shell都支持双方括号。在模式匹配中,可以定义一个正则表达式来匹配字符串值。

$ cat test24.sh
#!/bin/bash
#
if [[ $USER == r* ]]
then
echo "Hello $USER"
else
echo "Sorry, I do not know you"
fi
$
$ ./test24.sh
Hello rich
$

在上面的脚本中,我们使用了双等号( ==)。双等号将右边的字符串( r*)视为一个模式,
并应用模式匹配规则。双方括号命令$USER环境变量进行匹配,看它是否以字母r开头。如果是
的话,比较通过, shell会执行then部分的命令。

3. 最后我们来讲解 { }
**变量范围限定${} **
根据下面的shell 命令可见 如果变量 a 没有用{} 括起来的话,shell 就会将abc 识别为变量名。这显然不是我们想要的结果。

 $ a=123456
 $ echo $abc

 $ echo ${a}bc
123456bc
 $

命令分组 { ;;}
注意 “{” 后面需要有空格,“}” 前可以不需要空格 但是最后一条命令需要结束后也需要加“;” 。可以看到echo $BASH_SUBSHELL 输出的为 0,说明命令分组 { ;;} 并没有创建子shell 执行命令。

$ { ls ; ls ;echo  $BASH_SUBSHELL; }
123  223  323  tests.c
123  223  323  tests.c
0

关于shell 中各种括号的用法就分享到这啦,至于其他遗漏的用法,各位也可以留言,或者私信我,我再查漏补缺一下。(若无特别说明,本案列中的的shell 都是 bash shell 其他shell 可能会略有不同)

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐