除了修饰/偏好参数之外,原因之一可能是[ ! "$a" = "$b" ]与相比,在极端情况下失败的实现更多[ "$a" != "$b" ]。
如果实现遵循POSIX算法,则两种情况都应该是安全的,但是即使在今天(截至撰写本文的2018年初),仍然有一些实现失败的情况。例如,使用a='(' b=')':
$ (a='(' b=')'; busybox test "$a" != "$b"; echo "$?")
0
$ (a='(' b=')'; busybox test ! "$a" = "$b"; echo "$?")
1
对于dash0.5.9之前的版本,例如sh在Ubuntu 16.04上找到的0.5.8 :
$ a='(' b=')' dash -c '[ "$a" != "$b" ]; echo "$?"'
0
$ a='(' b=')' dash -c '[ ! "$a" = "$b" ]; echo "$?"'
1
(已在0.5.9中修复,请参见https://www.mail-archive.com/dash@vger.kernel.org/msg00911.html)
这些实现被[ ! "(" = ")" ]视为 [ ! "(" "text" ")" ]是[ ! "text" ](测试“文本”是否为空字符串),而POSIX则将其视为[ ! "x" = "y" ](测试“ x”和“ y”是否相等)。这些实现失败,因为在这种情况下它们执行了错误的测试。
请注意,还有另一种形式:
! [ "$a" = "$b" ]
那需要一个POSIX外壳(不适用于旧的Bourne外壳)。
请注意,几个实现也存在[ "$a" = "$b" ](和[ "$a" != "$b" ])问题,并且仍然像Solaris 10上的[内置功能一样/bin/sh(Bourne shell,POSIX shell在中/usr/xpg4/bin/sh)。这就是为什么您看到类似以下内容的原因:
[ "x$a" != "x$b" ]
在试图移植到旧系统的脚本中。
!(x==y)从(!x)==y。