Privilegiado

Privilegiado

¿Existe alguna diferencia en bash o un uso preferido de negación de una declaración?

if ! [[ -z "${var}" ]]; then
  do_something
fi

Versus

if [[ ! -z "${var}" ]]; then
  do_something
fi

Respuesta1

! [[ expression ]]

Esto será cierto si toda la prueba arroja falso

[[ ! expression ]]

Esto será cierto si la expresión individual devuelve falso.


Dado que la prueba puede ser una expresión compuesta, esto puede ser muy diferente. Por ejemplo:

$ [[ ! 0 -eq 1 || 1 -eq 1 ]] && echo yes || echo no
yes
$ ! [[ 0 -eq 1 || 1 -eq 1 ]] && echo yes || echo no
no

Personalmente prefiero usar la negación dentro de la construcción de prueba cuando corresponda, pero está perfectamente bien afuera dependiendo de su intención.

Respuesta2

A ! cmdes en realidad untubo, y !niega el código de salida delenterotubo.

De hombre bash:

Canalizaciones Una canalización es una secuencia de uno o más comandos separados por uno de los operadores de control | o |&. El formato de una canalización es:

         [time [-p]] [ ! ] command [ [|||&] command2 ... ]

...
Si la palabra reservada ! precede a una tubería, el estado de salida de esa tubería es la negación lógica del estado de salida como se describe anteriormente. El shell espera a que finalicen todos los comandos de la canalización antes de devolver un valor.

En ese sentido, un:

! [[ 2 -eq 2 ]]

Es la negación ( !) del código de salida del conjunto [[(una vez ejecutado todo). Por lo tanto, esto tiene un código de salida de 0:

!  [[ 2 -eq 2 && 3 -eq 4 ]]

Sin embargo

una [[ ! ]]es unacomando compuesto(no una pipa). De hombre bash:

Comandos compuestos
...
[[ expresión ]]
Devuelve un estado de 0 o 1 dependiendo de la evaluación de la expresión condicional.
Las expresiones se componen de los primarios que se describen a continuación en EXPRESIONES CONDICIONALES.

Por lo tanto, esto tiene un código de salida de 1:

[[ ! 2 -eq 2 && 3 -eq 4 ]]

Porque eso en realidad es equivalente a esto:

[[ ( ! 2 -eq 2 ) && ( 3 -eq 4 ) ]]

Lo cual, mediante evaluación de cortocircuito, el lado derecho de &&nunca se evalúa y en realidad es equivalente a esta expresión mucho más corta:

[[ ! 2 -eq 2 ]]

Lo cual siempre será falso (1).

En resumen: en el interior [[, el ! afectapartesde la expresión.

Privilegiado

Usar el !interior [[es mucho más común (y portátil a más shells (con [)), pero a veces puede resultar confuso si no se controla explícitamente mediante el uso juicioso de ()para delimitar el alcance de la negación (lo que podría convertirse en un problema dentro de [las construcciones).

Pero (en bash, ksh y zsh) el resultado ! [[está bastante claramente definido y es más fácil de entender: ejecuta el conjunto [[y niega el resultado.

Cuál debería usarse es una cuestión de preferencia personal (y comprensión).

información relacionada