Para aprovechar el perspicaz comentario de Chepner sobre la pregunta:
-
En
[ ! condition ]
, el!
es solo un argumento al[
incorporado (un alias efectivo deltest
incorporado); sucede que[
/test
interpreta el argumento!
como negación. -
En
! [ condition ]
, el!
es una palabra clave de shell que niega cualquier comando que le siga (que resulta ser[
en este caso).
Una cosa que el ! [ condition ]
la sintaxis implícitamente le da es que la negación se aplica a cualquier [ condition ]
evalúa a como un todo , por lo que si esa es la intención, no debe preocuparse por la precedencia del operador.
Desempeño inteligente , la sintaxis que elija probablemente no haga mucha diferencia; las pruebas rápidas sugieren:
-
Si
condition
es literalmente lo mismo en ambos casos, pasando el!
como un argumento para[
es insignificantemente más rápido. -
Si
!
se utiliza como palabra clave , y por lo tanto puede simplificar la condición al no preocuparse por la precedencia, puede ser un poco más rápido (por ejemplo,! [ 0 -o 1 ]
contra[ ! \( 0 -o 1 \) ]
; tenga en cuenta que la especificación POSIX. desaconseja el uso de-a
y-o
por ambigüedad).
Dicho esto, si hablamos de Bash , entonces deberías considerar usar [[
en lugar de [
, porque [[
es una palabra clave de shell que analiza la expresión adjunta en un contexto especial que:
- ofrece más funciones
- le permite combinar expresiones de forma segura con
&&
y||
- viene con menos sorpresas
- también es un poco más rápido (aunque eso rara vez importará en la práctica)
Mira esta respuesta mía.
!
niega el código de salida del siguiente comando:
$ ! test 1 = 1 || echo $? # negate command with true expression
1
Como se dice en la página man, test
(y similares [
incorporado) sale con el estado determinado por la siguiente expresión:
$ test ! 1 = 1 || echo $? # return false expression
1
$ [ ! 1 = 1 ] || echo $?
1
Para una expresión dada:
- por un lado niegas el
test
comando que sale con el estado de expresión verdadera. - por otro lado, niegas una expresión y el
test
comando (o[
) sale con su estado falso
Ambos tendrán el mismo efecto.
Entonces diría que estas sintaxis son equivalentes. Con la ventaja de !
externo para permitir pruebas compuestas negativas:
$ ! [ 1 = 1 -a 2 = 2 ] || echo $?
1