Per sfruttare il commento perspicace di Chepner sulla domanda:
-
In
[ ! condition ]
, il!
è solo un argomento al[
incorporato (un efficace alias deltest
incorporato); succede così che[
/test
interpreta l'argomento!
come negazione. -
In
! [ condition ]
, il!
è una parola chiave della shell che nega qualunque comando sia seguito da (che sembra essere[
in questo caso).
Una cosa che il ! [ condition ]
sintassi ti dà implicitamente che la negazione si applica a qualunque [ condition ]
valuta nel suo complesso , quindi se questo è l'intento, non devi preoccuparti della precedenza degli operatori.
Per quanto riguarda le prestazioni , quale sintassi scegli probabilmente non fa molta differenza; i test rapidi suggeriscono:
-
Se
condition
è letteralmente lo stesso in entrambi i casi, passando!
come argomento di[
è trascurabilmente più veloce. -
Se
!
viene utilizzato come parola chiave , e sei quindi in grado di semplificare la condizione senza preoccuparti della precedenza, potrebbe essere leggermente più veloce (ad esempio,! [ 0 -o 1 ]
contro[ ! \( 0 -o 1 \) ]
; si noti che la specifica POSIX. scoraggia l'uso di-a
e-o
per ambiguità).
Detto questo, se parliamo di Bash , allora dovresti prendere in considerazione l'utilizzo di [[
invece di [
, perché [[
è una parola chiave della shell che analizza l'espressione racchiusa in un contesto speciale che:
- offre più funzionalità
- ti consente di combinare in modo sicuro le espressioni con
&&
e||
- ha meno sorprese
- è anche leggermente più veloce (sebbene questo raramente abbia importanza nella pratica)
Vedi questa mia risposta.
!
nega il codice di uscita del seguente comando :
$ ! test 1 = 1 || echo $? # negate command with true expression
1
Come detto nella pagina man, test
(e simili [
builtin) esce con lo stato determinato dalla seguente espressione :
$ test ! 1 = 1 || echo $? # return false expression
1
$ [ ! 1 = 1 ] || echo $?
1
Per una data espressione :
- da un lato neghi il
test
comando che esce con lo stato di espressione vero. - d'altra parte, neghi un'espressione e il
test
comando (o[
) esce con il suo stato falso
Entrambi avranno lo stesso effetto.
Quindi direi che queste sintassi sono equivalenti. Con il vantaggio per !
esterno per consentire test composti negati :
$ ! [ 1 = 1 -a 2 = 2 ] || echo $?
1