Pour s'appuyer sur le commentaire perspicace de chepner sur la question :
-
Dans
[ ! condition ]
, le!
est juste un argument au[
intégré (un alias effectif dutest
intégré); il se trouve que[
/test
interprète l'argument!
comme négation. -
En
! [ condition ]
, le!
est un mot-clé shell qui annule toute commande suivie par (qui se trouve être[
dans ce cas).
Une chose que le ! [ condition ]
la syntaxe vous donne implicitement est que la négation s'applique à tout [ condition ]
évalue à dans son ensemble , donc si telle est l'intention, vous n'avez pas à vous soucier de la priorité des opérateurs.
En termes de performances , la syntaxe que vous choisissez ne fait probablement pas beaucoup de différence ; les tests rapides suggèrent :
-
Si
condition
est littéralement le même dans les deux cas, passant le!
comme argument de[
est négligeable plus rapide. -
Si
!
est utilisé comme mot-clé , et vous pouvez donc simplifier la condition en ne vous souciant pas de la priorité, cela peut être légèrement plus rapide (par exemple,! [ 0 -o 1 ]
contre[ ! \( 0 -o 1 \) ]
; notez que la spécification POSIX. décourage l'utilisation de-a
et-o
en raison de l'ambiguïté).
Cela dit, si nous parlons de Bash , alors vous devriez envisager d'utiliser [[
au lieu de [
, car [[
est un mot-clé shell qui analyse l'expression incluse dans un contexte spécial qui :
- offre plus de fonctionnalités
- vous permet de combiner en toute sécurité des expressions avec
&&
et||
- comporte moins de surprises
- est également légèrement plus rapide (bien que cela aura rarement de l'importance dans la pratique)
Voir ma réponse.
!
annule le code de sortie de la commande suivante :
$ ! test 1 = 1 || echo $? # negate command with true expression
1
Comme indiqué dans la page de manuel, test
(et similaire [
builtin) sortie avec le statut déterminé par l'expression suivante :
$ test ! 1 = 1 || echo $? # return false expression
1
$ [ ! 1 = 1 ] || echo $?
1
Pour une expression donnée :
- d'un côté vous annulez le
test
commande qui quitte avec le statut d'expression vrai. - de l'autre côté, vous niez une expression et le
test
commande (ou[
) sortie avec son statut faux
Les deux auront le même effet.
Je dirais donc que ces syntaxes sont équivalentes. Avec l'avantage pour le !
externe pour autoriser les tests composés négatifs :
$ ! [ 1 = 1 -a 2 = 2 ] || echo $?
1