Cuando escribo, generalmente escribo mis ifs con la siguiente sintaxis, ya que me resulta más fácil entender que lo que viene a continuación no es cierto.
if [ ! "$1" = "$2" ]; then
Otros dicen que el camino a continuación es mejor
if [ "$1" != "$2" ]; then
La cuestión es cuando pregunto por qué y si hay diferencias, nadie parece tener una respuesta.
Entonces, ¿hay alguna diferencia entre las dos sintaxis? ¿Es uno de ellos más seguro que el otro? ¿O es solo una cuestión de preferencia / hábito?
!(x==y)
entre(!x)==y
.if [ ! "$string" = "one" ]
traduce si no es el valor de$string
igualone
? ¿Y esto seif [ "$string" != "one"]
traduce en si el valor de$string
no es igual aone
?!=
sintaxis) es simplemente más obvio.Respuestas:
Además de los argumentos cosméticos / de preferencia, una razón podría ser que hay más implementaciones donde
[ ! "$a" = "$b" ]
falla en casos de esquina que con[ "$a" != "$b" ]
.Ambos casos deberían ser seguros si las implementaciones siguen el algoritmo POSIX , pero incluso hoy (a principios de 2018 a partir de la escritura), todavía hay implementaciones que fallan. Por ejemplo, con
a='(' b=')'
:Con
dash
versiones anteriores a 0.5.9, como la 0.5.8 encontrada comosh
en Ubuntu 16.04 por ejemplo:(corregido en 0.5.9, consulte https://www.mail-archive.com/[email protected]/msg00911.html )
Esas implementaciones se tratan
[ ! "(" = ")" ]
como[ ! "(" "text" ")" ]
es[ ! "text" ]
(prueba si "texto" es la cadena nula) mientras POSIX lo obliga a ser[ ! "x" = "y" ]
(prueba "x" e "y" para la igualdad). Esas implementaciones fallan porque realizan la prueba incorrecta en ese caso.Tenga en cuenta que todavía hay otra forma:
Ese requiere un shell POSIX (no funcionará con el antiguo shell Bourne).
Tenga en cuenta que varias implementaciones también han tenido problemas con
[ "$a" = "$b" ]
(y[ "$a" != "$b" ]
) y todavía les gusta la[
creación de/bin/sh
Solaris 10 (un shell Bourne, estando el shell POSIX/usr/xpg4/bin/sh
). Por eso ves cosas como:En scripts que intentan ser portables a sistemas antiguos.
fuente
! "$a" = "b"
deben ser más cuidadosos con la forma en que la escriben para especificar la comparación. Por su ejemplo, entiendo que el segundo comando regresa, lonot zero
que podría ser beneficioso o problemático. Podría ser beneficioso si desea salir si no coinciden, o preocuparse si desea ver si la comparación se estrelló[ ! "$a" = "$b" ]
simplemente falla cuando$a
es(
y$b
es)
, afirma que son idénticas cuando no lo son,(
no es la misma cadena que)
, pero[
realiza la prueba incorrecta en ese caso.[ ! "$a" = "$b" ]
veces se maneja incorrectamente en implementaciones de shell con errores (lo que creo que es más o menos reformular la primera oración de la respuesta).La
x != y
sintaxis es mejor porque! x == y
es propensa a errores: requiere el conocimiento de la precedencia de los operadores que difiere de un idioma a otro. La sintaxis! x == y
podría interpretarse como!(x == y)
o(!x) == y
, dependiendo de la prioridad de!
frente=
.Por ejemplo, en la
c++
negación!
viene antes del operador de comparación / relacional==
, de ahí el siguiente código:devoluciones
Se puede observar un comportamiento similar en muchos otros idiomas, incluido, por ejemplo
awk
, una herramienta de uso frecuente en el mundo Unix.Por otro lado, reunir a los operadores a través de
x != y
no genera confusión como un patrón bien establecido. Además, técnicamente hablando, a!=
menudo no son dos, sino un solo operador, por lo que debería ser incluso más rápido de evaluar que una comparación separada y luego la negación. Por lo tanto, aunque ambas sintaxis funcionan en bash, recomendaría seguirlas,x != y
ya que es mucho más fácil leer y mantener el código que sigue cierta lógica estándar.fuente
Este tipo de cosas está muy basado en la opinión, ya que la "respuesta" depende en gran medida de la forma en que el cerebro de un individuo está conectado. Si bien es cierto que semánticamente,
NOT ( A == B )
es idéntico a(A != B )
uno, uno podría ser más claro para una persona y el otro para otra. También depende del contexto. Por ejemplo, si tengo un conjunto de indicadores, los significados pueden ser más claros con una sintaxis sobre otra:Opuesto a
fuente
if ( FS_OPEN != fileHandleStatus )
como resultado de la facilidad de escribir accidentalmente en=
lugar de==
en lenguajes donde el primero es la asignación y la prueba de igualdad posterior (como C) ...