Linux shell编程学习笔记23:[] [[]]的用法小结

上回梳理 了Linux Shell编程中 () 、$()和 (())的用法,现在接着梳理 [] 和[[]]的用法。

1 单中括号(方括号)[]


1.1 检测某个条件是否成立


[和test等同,是 Shell 内置命令,用来检测某个条件是否成立。条件成立时退出状态为 0,否则为非 0 值。

1.1.1 字符串比较运算

1.1.1.1 ==(或=) 和  !=

Test和[]中,可用的比较运算符只有 ==(或=) 和  !=,两者都是用于字符串比较的,不可用于整数比较。

  • 在不引起歧义的情况下,[]中的变量名可以不加$前缀。

实例:

我们先定义字符串s1="abc"和s2="def"

然后在[]中分别使用==和!=来在bash和zsh进行测试。

1.在bash中

[csdn ~]$ s1="abc"; s2="def"
[csdn ~]$ echo $[ $s1 != $s2 ] 
0
[csdn ~]$ if [ $s1 != $s2 ] ; then echo s1=$s1; else echo s2=$s2; fi 
s1=abc
[csdn ~]$ echo $[ $s1 == $s2 ] 
1
[csdn ~]$ if [ $s1 == $s2 ] ; then echo s1=$s1; else echo s2=$s2; fi 
s2=def
[csdn ~]$ echo $[ s1 == s2 ] 
1
[csdn ~]$ 

2.在zsh中

csdn @ edu $ s1="abc"
csdn @ edu $ s1="abc";s2="def"
csdn @ edu $ echo $[ $s1 != $s2 ]
0
csdn @ edu $ if [ $s1 != $s2 ] ; then echo s1=$s1; else echo s2=$s2; fi 
else> 
csdn @ edu $ echo $[ $s1 == $s2 ]
1
csdn @ edu $ if [ $s1 == $s2 ] ; then echo s1=$s1; else echo s2=$s2; fi 
else>       
csdn @ edu $ echo $[ s1 == s2 ] 

csdn @ edu $ 

1.1.1.2 < 和 >

对字符串比较,是否直接可用使用大于号(>)和小于号(<)呢?

1.在bash中

[csdn ~]$ s1="abc"
[csdn ~]$ s2="def"
[csdn ~]$ echo $[ $s1 > $s2 ]
0
[csdn ~]$ [ $s1 \> $s2 ]
[csdn ~]$ echo $?
1
[csdn ~]$ echo $[ $s1 < $s2 ]
0
[csdn ~]$ [ $s1 \< $s2 ]
[csdn ~]$ echo $?
0
[csdn ~]$ 

在上面的例子中,我们先定义了字符串变量s1="abc"和 s2="def",然后在[]中直接使用  > 和 < 对s1和s2进行比较,显示结果都是1,明显有问题。

当我们在[]中使用 \> 和 \< 来对s1和s2进行比较,结果分别是1和0,这才是正确的结果。

 可见,在bash中,对于字符串比较,可以使用转义形式用大于号(>)和小于号(<)。

2.在zsh中

user # csdn zsh $ s1="abc"           
user # csdn zsh $ s2="def"           
user # csdn zsh $ echo $[ $s1 > $s2 ]
0
user # csdn zsh $ [ $s1 \> $s2 ]    
zsh: condition expected: >
user # csdn zsh $ echo $?
1
user # csdn zsh $ echo $[ $s1 < $s2 ]
0
user # csdn zsh $ [ $s1 \< $s2 ]     
zsh: condition expected: <
user # csdn zsh $ echo $?
1

在上面的例子中,我们同样先定义了字符串变量s1="abc"和 s2="def",然后在[]中直接使用  > 和 < 对s1和s2进行比较,显示结果都是0,与bash中不同,但同样明显有问题。

当我们在[]中使用 \> 和 \< 来对s1和s2进行比较,zsh不支持。

字符范围。用作正则表达式的一部分,描述一个匹配的字符范围。作为test用途的中括号内不能使用正则。

1.1.2 整数比较运算

1.1.2.1 -eq,-gt等

Test和[]中, 整数比较可以使用-eq,-gt这类形式。

1.1.2.1.1 在bash中

[csdn ~]$ i=1; let i++; echo i=$i; j=12;let j--;echo j=$j 
i=2
j=11
[csdn ~]$ [ $i -lt $j ]
[csdn ~]$ echo $?
0
[csdn ~]$ [ $i -gt $j ]
[csdn ~]$ echo $?
1

1.1.2.1.2 在zsh中

csdn @ edu $ i=1; let i++; echo i=$i; j=12;let j--;echo j=$j     
i=2
j=11
csdn @ edu $ [ $i -lt $j ]                                   
csdn @ edu $ echo $?
0
csdn @ edu $ [ $i -gt $j ]
csdn @ edu $ echo $?
1

 

 1.1.2.2 < 和 >

在大多编程变语言中,对Linux shell中的整数比较,是否直接可用使用大于号(>)和小于号(<)呢?

1.1.2.1.1在bash中

[csdn ~]$ i=1; let i++; echo i=$i; j=12;let j--;echo j=$j 
i=2
j=11 
[csdn ~]$ echo $[ i > j ]
0
[csdn ~]$ echo $[ i < j ]
1
[csdn ~]$ echo $[ i \< j ]
bash: i \< j : syntax error: invalid arithmetic operator (error token is "\< j ")
[csdn ~]$ [ i \< j ]
[csdn ~]$ echo $?
0
[csdn ~]$ [ i \> j ]
[csdn ~]$ echo $?
1

在上面的实例中,我们定义了整数变量i和j,

先直接使用 > 和 < 来比较i和j,结果分别是0和1,这个结果按字符串来比较是对的,但按整数来比较是错误的。

接着我们使用 \< 和 \> 来对i和j进行比较,结果分别是0和1,正确。

以下是按字符串来比较的结果。

[csdn ~]$ i='2'; j="11"
[csdn ~]$ echo $[ i > j ]
0
[csdn ~]$ echo $[ i < j ]
1

1.1.2.1.2 在zsh中

csdn @ edu $ i=1; let i++; echo i=$i; j=12;let j--;echo j=$j 
i=2
j=11
csdn @ edu $ echo $[ j > j ] 
0
csdn @ edu $ echo $[ j < j ] 
0
csdn @ edu $ echo $[ j \< j ] 
zsh: bad math expression: illegal character: \
csdn @ edu $ echo $[ j \> j ] 
zsh: bad math expression: illegal character: \

 

在上面的实例中,我们同样是定义了整数变量i和j,

先直接使用 > 和 < 来比较i和j,结果都是0,显示有问题。

接着我们使用 \< 和 \> 来对i和j进行比较,结果zsh不支持。 

1.1.3 逻辑运算

  • [ ]中的逻辑与 使用 -a  表示(and),和逻辑或使用  -o 表示(or)。
  • [ ]之间的逻辑与 使用 &&  表示(and),和逻辑或使用  || 表示(or)。

1.1.3.1 在bash中

[csdn ~]$ s1='a';s2='b';s3='a'
[csdn ~]$ [ $s1 == $s2 -o $s1 == $s3 ]
[csdn ~]$ echo $?
0
[csdn ~]$ [ $s1 == $s2 ] || [ $s1 == $s3 ]
[csdn ~]$ echo $?
0
[csdn ~]$  [ $s1 == $s2 -a $s1 == $s3 ]
[csdn ~]$ echo $?
1
[csdn ~]$ [ $s1 == $s2 ] && [ $s1 == $s3 ]
[csdn ~]$ echo $?
1

在上面的实例中,我们先定义了三个字符串变量: s1='a';s2='b';s3='a'

然后执行 [ $s1 == $s2 -o $s1 == $s3 ] , s1 == $s2 结果为1,$s1 == $s3结果为0,由于我们使用的是 -o (or ),所以结果为0

接着用命令  echo $? 来显示结果:0

然后的 [ $s1 == $s2 ] || [ $s1 == $s3 ] 和  [ $s1 == $s2 -o $s1 == $s3 ]是一样的。

接着执行 [ $s1 == $s2 -a $s1 == $s3 ] ,s1 == $s2 结果为1,$s1 == $s3结果为0,由于我们使用的是 -a (and ),所以结果为1

最后用命令  echo $? 来显示结果:0

1.1.3.2 在zsh中

csdn @ edu zsh $ s1='a';s2='b';s3='a'
csdn @ edu zsh $ [ $s1 == $s2 -o $s1 == $s3 ]
zsh: = not found
csdn @ edu zsh $ [ $s1 = $s2 -o $s1 = $s3 ] 
csdn @ edu zsh $ echo $?
0
csdn @ edu zsh $ [ $s1 == $s2 ] || [ $s1 == $s3 ]
zsh: = not found
csdn @ edu zsh $ [ $s1 = $s2 ] || [ $s1 = $s3 ] 
csdn @ edu zsh $ echo $?                         
0
csdn @ edu zsh $ [ $s1 = $s2 -o $s1 = $s3 ] 
csdn @ edu zsh $ echo $?                   
0
csdn @ edu zsh $ [ $s1 = $s2 ] && [ $s1 = $s3 ] 
csdn @ edu zsh $ echo $?                       
1

上面的实例与bash中是一样的,不过zsh不支持 == ,我们改为 = 。

1.2 引用数组中每个元素

对数组来说,中括号可以用来按下标索引访问数组元素。

1.2.1 在bash中

 [csdn ~]$ a=(1 2 3)
[csdn ~]$ echo ${a[1]}
2
[csdn ~]$ echo ${a[*]}
1 2 3

在上面实例中,我们先定义数组 a=(1 2 3)

然后用命令 echo ${a[1]} 显示数组中的第2个元素,bash中数组下标从0开始。

接着用命令 echo ${a[*]} 显示数组中的所有元素。

1.2.2 在zsh中

csdn @edu zsh $ a=(1 2 3)
csdn @edu zsh $ echo $a[1]
1
csdn @edu zsh $ echo $a[*]
1 2 3
csdn @edu zsh $ echo ${a[1]}
1
csdn @edu zsh $ echo ${a[*]}
1 2 3

在上面实例中,我们先定义数组 a=(1 2 3)

然后用命令 echo ${a[1]} 显示数组中的第1个元素,bash中数组下标从1开始。

接着用命令 echo ${a[*]} 显示数组中的所有元素。

2 双中括号(方括号)[[]]

[[ ]]是 Shell 内置关键字,它的功能和 [] 或 test 命令类似,也用来检测某个条件是否成立。

 [[ ]] 是 [] 或 test 的升级版,对细节进行了优化,并且扩展了一些功能。

  • [] 或 test 能做到的,[[ ]] 也能做到,而且 [[ ]] 做的更好;
  • [] 或 test 做不到的,[[ ]] 还能做到。

2.1 [[ ]] 支持字符串、整数比较运算 和 逻辑运算

2.1.1 在bash中

[csdn ~]$ s1='a';s2='b';s3='a'
[csdn ~]$ [ $s1 = $s2 || $s1 = $s3 ]
bash: [: missing `]'
bash: a: command not found
[csdn ~]$ [[ $s1 = $s2 || $s1 = $s3 ]]
[csdn ~]$ echo $?
0
[csdn ~]$ [[ $s1 = $s2 -o $s1 = $s3 ]]
bash: syntax error in conditional expression
bash: syntax error near `-o'
[csdn ~]$ [ $s1 = $s2 && $s1 = $s3 ]
bash: [: missing `]'
[csdn ~]$ [[ $s1 = $s2 && $s1 = $s3 ]]
[csdn ~]$ echo $?
1
[csdn ~]$ [[ $s1 = $s2 -a $s1 = $s3 ]]
bash: syntax error in conditional expression
bash: syntax error near `-a'

2.1.2 在zsh中

csdn @ edu zsh $ s1='a';s2='b';s3='a'        
csdn @ edu zsh $ [ $s1 = $s2 || $s1 = $s3 ]  
[: ']' expected
zsh: command not found: a
csdn @ edu zsh $ [[ $s1 = $s2 || $s1 = $s3 ]]
csdn @ edu zsh $ echo $?
0
csdn @ edu zsh $ [[ $s1 = $s2 -o $s1 = $s3 ]]
zsh: condition expected: $s1
csdn @ edu zsh $ [ $s1 = $s2 && $s1 = $s3 ] 
[: ']' expected
csdn @ edu zsh $ [[ $s1 = $s2 && $s1 = $s3 ]]
csdn @ edu zsh $ echo $?
1
csdn @ edu zsh $ [[ $s1 = $s2 -a $s1 = $s3 ]]
zsh: condition expected: $s1

在 [[ ]]  中支持使用 && 和 ||,不支持 -o 和 -a。 

2.2 支持正则表达式

在 Shell [[ ]] 中,可以使用=~来检测字符串是否符合某个正则表达式,其用法为:

[[ 字符串 =~ 正则表达式 ]]

例如:

  • ^[0-9]*$ 是检测是否为纯数字字符串的正则表达式
  • ^[a-z]*$ 是检测是否为纯小写字母字符串的正则表达式

2.2.1 在bash中

[csdn ~]$ s="12345"; [[ $s =~ ^[0-9]*$ ]]; echo $?
0
[csdn ~]$ s="12345abc"; [[ $s =~ ^[0-9]*$ ]]; echo $?
1
[csdn ~]$ s="12345"; [[ $s =~ ^[a-z]*$ ]]; echo $?
1
[csdn ~]$ s="abc"; [[ $s =~ ^[a-z]*$ ]]; echo $?
0

2.2.2 在zsh中

csdn @ edu zsh $ s="12345"; [[ $s =~ ^[0-9]*$ ]]; echo $?   
0
csdn @ edu zsh $ s="12345abc"; [[ $s =~ ^[0-9]*$ ]]; echo $?
1
csdn @ edu zsh $ s="12345"; [[ $s =~ ^[a-z]*$ ]]; echo $?
1
csdn @ edu zsh $ s="abc"; [[ $s =~ ^[a-z]*$ ]]; echo $?
0

 

2.2.3 注意

为了确保[[]]取得正确结果,其中的变量名要加上$前缀。

在bash中:

[csdn ~]$ s="12345"; [[ s =~ ^[0-9]*$ ]]; echo $?
1
[csdn ~]$ s="12345"; [[ $s =~ ^[0-9]*$ ]]; echo $?
0
[csdn ~]$ s="abc"; [[ s =~ ^[0-9]*$ ]]; echo $?
1
[csdn ~]$ s="abc"; [[ $s =~ ^[0-9]*$ ]]; echo $?
1
[csdn ~]$ s="abc"; [[ s =~ ^[a-z]*$ ]]; echo $?
0
[csdn ~]$ s="abc"; [[ $s =~ ^[a-z]*$ ]]; echo $?
0
[csdn ~]$ s="123"; [[ s =~ ^[a-z]*$ ]]; echo $?
0
[csdn ~]$ s="123"; [[ $s =~ ^[a-z]*$ ]]; echo $?
1

 

猜你喜欢

转载自blog.csdn.net/Purpleendurer/article/details/134308917