Além dos argumentos cosméticos / preferenciais, uma razão pode ser que existam mais implementações nas quais [ ! "$a" = "$b" ]
falha em casos de canto do que com [ "$a" != "$b" ]
.
Ambos os casos devem ser seguros se as implementações seguirem o algoritmo POSIX , mas mesmo hoje (início de 2018, por escrito), ainda existem implementações que falham. Por exemplo, com a='(' b=')'
:
$ (a='(' b=')'; busybox test "$a" != "$b"; echo "$?")
0
$ (a='(' b=')'; busybox test ! "$a" = "$b"; echo "$?")
1
Com dash
versões anteriores à 0.5.9, como a 0.5.8 encontrada como sh
no Ubuntu 16.04, por exemplo:
$ a='(' b=')' dash -c '[ "$a" != "$b" ]; echo "$?"'
0
$ a='(' b=')' dash -c '[ ! "$a" = "$b" ]; echo "$?"'
1
(corrigido em 0.5.9, consulte link )
Essas implementações tratam [ ! "(" = ")" ]
como [ ! "(" "text" ")" ]
que é [ ! "text" ]
(teste se "texto" é a cadeia nula) enquanto POSIX ordena que seja [ ! "x" = "y" ]
(teste "x" e "y" para igualdade) . Essas implementações falham porque executam o teste errado nesse caso.
Note que ainda existe outra forma:
! [ "$a" = "$b" ]
Esse requer um shell POSIX (não funciona com o shell antigo do Bourne).
Observe que várias implementações tiveram problemas com [ "$a" = "$b" ]
(e [ "$a" != "$b" ]
) também a> e ainda gosto do [
embutido de /bin/sh
no Solaris 10 (um shell Bourne, sendo o shell POSIX em /usr/xpg4/bin/sh
). É por isso que você vê coisas como:
[ "x$a" != "x$b" ]
Em scripts que tentam ser portáteis para sistemas antigos.