bash中的()、(())、[]、[[]]、{}

总结bash编程中的这些特殊符号

()

单小括号在shell中的两个作用:

  • 初始化数组
  • $(commands)启动一个新shell执行单个命令或者是多个命令

初始化数组

1
arr=(1 2 3 4)

执行单个命令

1
2
3
x=$(ls -al)
#等效于
x='ls -al'

执行多个命令

1
$(cd ./;ls -al;)

需要注意点:

  • 每个命令使用;分隔,最后一个命令可以使用;也可以不用

(())

双小括号仅仅用于整数的处理,只要括号中的运算符、表达式符合C语言运算规则,都可用在$((exp))中,甚至是三目运算符。作不同进位(如二进制、八进制、十六进制)运算时,输出结果全都自动转化成了十进制。如:echo $((16#5f)) 结果为95 (16进位转十进制)

双括号中的变量可以不使用$符号前缀。括号内支持多个表达式用逗号分开。 只要括号中的表达式符合C语言运算规则,比如可以直接使用for((i=0;i<5;i++)), 如果不使用双括号, 则为

1
for i in `seq 0 4`

或者for i in {0..4}。再如可以直接使用if (($i<5)), 如果不使用双括号, 则为if [ $i -lt 5 ]


[]

bash 的内部命令,[和test是等同的。此运算符的作用有四个:

  • 文件比较
  • 整数比较
  • 字符串比较
  • 逻辑比较

文件比较

整数比较

注意点:

  • Test和[]中可用的比较运算符只有==!=,两者都是用于字符串比较的,不可用于整数比较,整数比较只能使用-eq-gt这种形式。无论是字符串比较还是整数比较都不支持大于号小于号。如果实在想用,对于字符串比较可以使用转义形式,如果比较”ab”和”bc”:[ ab \< bc ],但是无法转移>= <=。所以最好还是在[]中使用字母。
  • 中间无法使用正则表达式

字符串比较

注意点:

  • []首尾必须有空格

逻辑比较

[ ]中的逻辑与和逻辑或使用-a-o表示。

1
2
3
[ $a -e $b -a $c -eq $b ]
#或
if [ $a -ne 1] && [ $a != 2 ]

注意点:

  • 上面不要:[ ($a -e $b) -a ($c -eq $b) ]会报错
  • 注意两边的空格

[[]]

双括号表达式是[]的扩展,添加了正则表达式的支持。并且不同于[]的逻辑符号是-a -o [[]]允许使用 && ||。如下:

1
if [[ $a != 1 && $a != 2 ]]   

https://taoshu.in/unix/test-bracket.html#fn1

上面这篇文章写了shell中的[[[之间关系


{}

大括号有三个作用:

  • 扩展,对于{}内的以逗号分割的文件列表进行拓展。或者对大括号中以点点(..)分割的顺序文件列表起拓展作用。
  • 包含多个命令在本shell中执行,{cd;ls -al;cd -;}()不同的是最后一个命令后必须有;,而()不做要求。并且第一条命令和左括号之间必须用空格隔开。
  • 函数块

扩展

1
2
3
4
5
6
# ls {ex1,ex2}.sh    
ex1.sh ex2.sh
# ls {ex{1..3},ex4}.sh
ex1.sh ex2.sh ex3.sh ex4.sh
# ls {ex[1-3],ex4}.sh
ex1.sh ex2.sh ex3.sh ex4.sh

函数

1
2
3
4
5
6
7
function name {

}
#或
name() {

}

对于字符串的操作

记忆方法:
#位于$的右边,所以#是从右边开始;%$左边,所以是从左边开始

例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# var=/home/centos  
# echo $var
/home/centos
# echo ${var:5}
/centos
# echo ${var: -6}
centos
# echo ${var:(-6)}
centos
# echo ${var:1:4}
home
# echo ${var/o/h}
/hhme/centos
# echo ${var//o/h}
/hhme/cenths

# var=testcase
# echo $var
testcase
# echo ${var%s*e}
testca
# echo $var
testcase
# echo ${var%%s*e}
te
# echo ${var#?e}
stcase
# echo ${var##?e}
stcase
# echo ${var##*e}

# echo ${var##*s}
e
# echo ${var##test}
case

#发现输出的内容是var去掉pattern的那部分字符串的值

几种特殊的替换结构

1
2
3
4
${var:-string} 
${var:+string}
${var:=string}
${var:?string}
  1. ${var:-string}${var:=string}:若变量var为空,则用在命令行中用string来替换${var:-string},否则变量var不为空时,则用变量var的值来替换${var:-string};对于${var:=string}的替换规则和${var:-string}是一样的,所不同之处是${var:=string}若var为空时,用string替换${var:=string}的同时,把string赋给变量var: ${var:=string}很常用的一种用法是,判断某个变量是否赋值,没有的话则给它赋上一个默认值。

  2. ${var:+string}的替换规则和上面的相反,即只有当var不是空的时候才替换成string,若var为空时则不替换或者说是替换成变量 var的值,即空值。(因为变量var此时为空,所以这两种说法是等价的)

  3. {var:?string}替换规则为:若变量var不为空,则用变量var的值来替换${var:?string};若变量var为空,则把string输出到标准错误中,并从脚本中退出。我们可利用此特性来检查是否设置了变量的值。

补充扩展:在上面这五种替换结构中string不一定是常值的,可用另外一个变量的值或是一种命令的输出。


总结

  1. 只有[]中不可以直接使用数学比较符号如< >等等,要使用也是要转义的\>,但是无法转移>= <=。所以最好还是在[]中使用字母。

参考资料

https://www.runoob.com/w3cnote/linux-shell-brackets-features.html

https://www.cnblogs.com/hkui/p/6423918.html

https://math.ecnu.edu.cn/~jypan/Teaching/Linux/Linux08/lect14_Review.pdf


bash中的()、(())、[]、[[]]、{}
https://ysc2.github.io/ysc2.github.io/2023/12/10/bash中的()、(())、[]、[[]]、{}/
作者
Ysc
发布于
2023年12月10日
许可协议