¿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 ! cmd
es 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).