Além dos argumentos cosméticos / de preferência, um motivo pode ser o fato de haver mais implementações em que [ ! "$a" = "$b" ]falhas nos casos de canto do que com [ "$a" != "$b" ].
Ambos os casos devem ser seguros se as implementações seguirem o algoritmo POSIX , mas ainda hoje (início de 2018), 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 dashversões anteriores à 0.5.9, como a 0.5.8 encontrada shno 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 https://www.mail-archive.com/dash@vger.kernel.org/msg00911.html )
Essas implementações tratam [ ! "(" = ")" ]como [ ! "(" "text" ")" ]é [ ! "text" ](teste se "texto" é a cadeia nula), enquanto o POSIX exige que seja [ ! "x" = "y" ](teste "x" e "y" para igualdade). Essas implementações falham porque executam o teste errado nesse caso.
Observe que há ainda outra forma:
! [ "$a" = "$b" ]
Esse requer um shell POSIX (não funcionará com o shell Bourne antigo).
Observe que várias implementações também tiveram problemas com [ "$a" = "$b" ](e [ "$a" != "$b" ]) e ainda se assemelham às [do /bin/shSolaris 10 (um shell Bourne, o shell POSIX está dentro /usr/xpg4/bin/sh). É por isso que você vê coisas como:
[ "x$a" != "x$b" ]
Em scripts, tentando ser portável para sistemas antigos.
!(x==y)a partir(!x)==y.