我正在阅读关于if的bash示例,但一些示例用单方括号编写:

if [ -f $param ]
then
  #...
fi

其他带有双方括号的:

if [[ $? -ne 0 ]]
then
    start looking for errors in yourlog
fi

有什么不同?


当前回答

[[是一个bash关键字,类似于[命令(但比[命令更强大)。

See

http://mywiki.wooledge.org/BashFAQ/031和http://mywiki.wooledge.org/BashGuide/TestsAndConditionals

除非您正在编写POSIX sh,否则我们推荐[[。

其他回答

你可以使用双方括号进行简单的正则表达式匹配,例如:

如果[[$1 =~ "*bar"]];然后

(只要您使用的bash版本支持此语法)

在单括号内用于条件测试(即[…]]),所有shell都支持一些操作符,例如单个=,而一些较老的shell不支持使用operator ==。

在双括号内用于条件测试(即[[…]]]),在旧shell和新shell中使用=或==没有区别。

编辑:我还应该注意:在bash中,总是使用双括号[[…]]],因为它比单括号更安全。我将用下面的例子来说明原因:

if [ $var == "hello" ]; then

如果$var恰好是空的,那么这是脚本看到的:

if [ == "hello" ]; then

这会破坏你的剧本。解决方案是使用双括号,或者总是记得在变量周围加上引号(“$var”)。双括号是更好的防御性编码实践。

单个[]是posix shell兼容的条件测试。

Double[[]]是标准[]的扩展,bash和其他shell(例如zsh, ksh)都支持它。它们支持额外的操作(以及标准的posix操作)。例如:||代替-o, regex匹配=~。在bash手册中关于条件构造的部分中可以找到更完整的差异列表。

当您希望您的脚本可以跨shell移植时,请使用[]。如果您想要[]不支持的条件表达式并且不需要可移植,请使用[[]]。

[[是一个bash关键字,类似于[命令(但比[命令更强大)。

See

http://mywiki.wooledge.org/BashFAQ/031和http://mywiki.wooledge.org/BashGuide/TestsAndConditionals

除非您正在编写POSIX sh,否则我们推荐[[。

像printf一样是内置的。Bash语法希望在与命令相同的位置看到它。并且]对Bash来说没什么,除了[内置的。(man bash / SHELL内置命令) [[是类似if的关键字。Bash语法开始时也期望它与命令位于同一位置,但它不是执行它,而是进入条件上下文。[]也是结束此上下文的关键字。(man bash / SHELL语法/复合命令)

格式关键字>用户别名>内置函数>用户函数> $PATH中的命令

type [  # [ is a shell builtin
type [[  # [[ is a shell keyword
type ]  # bash: type: ]: not found
type ]]  # ]] is a shell keyword
compgen -k  # Keywords: if then else ...
compgen -b  # Builtins: . : [ alias bg bind ...
which [  # /usr/bin/[

[更慢,<=它执行更多的解析代码,我猜。但我知道它调用相同数量的系统调用(测试用 [[在语法上更容易解析,甚至对人类来说,因为它开始了一个上下文。对于算术条件,考虑使用((。

time for i in {1..1000000}; do [ 'a' = 'b' ] ; done  # 1.990s
time for i in {1..1000000}; do [[ 'a' == 'b' ]] ; done  # 1.371s

time for i in {1..1000000}; do if [ 'a' = 'a' ]; then if [ 'a' = 'b' ];then :; fi; fi ; done  # 3.512s
time for i in {1..1000000}; do if [[ 'a' == 'a' ]]; then if [[ 'a' == 'b' ]];then :; fi; fi; done  # 2.143s

strace -cf  bash -c "for i in {1..100000}; do if [ 'a' = 'a' ]; then if [ 'a' = 'b' ];then :; fi; fi  ; done;"  # 399
strace -cf  bash -c "for i in {1..100000}; do if [[ 'a' == 'a' ]]; then if [[ 'a' == 'b' ]];then :; fi; fi  ; done;"  # 399

我建议使用[[:如果你不显式地关心posix兼容性,这意味着你不关心,所以不要关心获得“更多”兼容性的脚本。