shell中的单括号和双括号

介绍下shell中的单双括号的使用问题

使用

使用场景

刚开始写shell的时候,部分和同事一般都是建议用双中括号, 因为在某些场景下,[]不能使用 具体是哪些场景呢?感兴趣的也可以看看https://tldp.org/LDP/abs/html/testconstructs.html#DBLBRACKETS

通配符匹配

1
2
3
4
5
liuliancao@liuliancao:~$ [ ab == a* ] && echo "matched" || echo "not matched"
-bash: [: too many arguments
not matched
liuliancao@liuliancao:~$ [[ ab == a* ]] && echo "matched" || echo "not matched"
matched

条件里面包含&& ||

1
2
3
4
liuliancao@liuliancao:~$ [ 'a' == 'a' && 'a' != 'b' ] && echo 'a is a. ovo'
-bash: [: missing `]'
liuliancao@liuliancao:~$ [[ 'a' == 'a' && 'a' != 'b' ]] && echo 'a is a. ovo'
a is a. ovo

字符串比较大小

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
liuliancao@liuliancao:~$ [ "a" > "a" ] && echo 'ab > a.'
ab > a.
liuliancao@liuliancao:~$ [[ "a" > "a" ]] && echo 'ab > a.'
liuliancao@liuliancao:~$ [[ "abc" > "aba" ]] && echo 'abc > aba.' || echo 'abc < aba'
abc > aba.
liuliancao@liuliancao:~$ [[ "abc" > "abd" ]] && echo 'abc > abd.' || echo 'abc < abd'
abc < abd
liuliancao@liuliancao:~$ [[ abc > aba ]] && echo 'abc > aba.' || echo 'abc < aba'
abc > aba.

liuliancao@liuliancao:~$ [ "a" < "ab" ] && echo 'a < ab.'
-bash: ab: No such file or directory
liuliancao@liuliancao:~$ [ "a" \< "ab" ] && echo 'a < ab.'
a < ab.

这里还需要注意,字符串在[]需要包起来且不是<>才会不报错,但是总是true,和结果预期不符, 而如果要满足预期,需要 加上转义\, 无论是小于还是大于,这里的原因其实是[]本质上是posix风格的命令,和curl那些命令一样,在则是一个bash扩展 有点像一个函数 而在双中括号里面,其实可以不包

字符替换

1
2
3
4
5
liuliancao@liuliancao:~$ [ "${a//123/321}" == $(ls -al) ] && echo "splitted" || echo "no split"
-bash: [: too many arguments
no split
liuliancao@liuliancao:~$ [[ "${a//123/321}" == $(ls -al) ]] && echo "splitted" || echo "no split"
no split

只有[]才可以的

非bash环境中

如果以下面方式开头,双中括号会报错,建议以bash开头 #!/usr/bin/env sh #!/bin/sh

其他条件工具

test

1
test和[]本质是一样的

expr

expr是真假,真为1,也就是$(expr a \> b)是0, $(expr a \< b)是1,但是$?都是0

1
2
3
4
liuliancao@liuliancao:~$ expr a \< b
1
liuliancao@liuliancao:~$ expr a \> b
0

总结

  • 一般建议在确认用bash的场景使用
  • 如果确定不会用到上述特性,使用[]也无妨,需要充分测试
  • 特殊场景记得转义