[ a = a -a b = b ]:几乎等价,但被POSIX弃用,因为它是疯狂的,并且对于a或b的某些值(如!或()会失败,这些值将被解释为逻辑操作
< p > (
[[ (a = a || a = b) && a = b ]]:假的。如果没有( ),则为真,因为[[ && ]]的优先级高于[[ || ]]
[ ( a = a ) ]:语法错误,()被解释为子shell
[ \( a = a -o a = b \) -a a = b ]:等价的,但是(), -a和-o被POSIX弃用。如果没有\( \),则为真,因为-a的优先级比-o高
{ [ a = a ] || [ a = b ]; } && [ a = b ]非弃用POSIX等价。然而,在这种特殊情况下,我们可以只写:[ a = a ] || [ a = b ] && [ a = b ],因为||和&& shell操作符具有相同的优先级,不像[[ || ]]和[[ && ]]和-o, -a和[
字拆分和文件名生成扩展(split+glob)
x='a b'; [[ $x = 'a b' ]]: true,不需要引号
x='a b'; [ $x = 'a b' ]:语法错误,扩展为[ a b = 'a b' ]
x='*'; [ $x = 'a b' ]:如果当前目录中有多个文件,将会出现语法错误。
x='a b'; [ "$x" = 'a b' ]: POSIX等价
< p > =
[[ ab = a? ]]: true,因为它执行模式匹配 (* ? [是魔法)。不会将glob扩展到当前目录下的文件。
[ ab = a? ]: a? glob扩展。因此,根据当前目录中的文件,可能为真或假。
[ ab = a\? ]: false,不是glob扩展
=和==在[和[[中是相同的,但==是一个Bash扩展。
case ab in (a?) echo match; esac: POSIX等价
[[ ab =~ 'ab?' ]]: false,在Bash 3.2及以上版本中失去与''的魔力,并提供对Bash 3.1的兼容性未启用(如BASH_COMPAT=3.1)
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