n'utilisez jamais l'opérateur `-a` ou` -o` avec `[`

11

Stéphane Chazelas a écrit:

quelques règles comme

  • toujours citer des variables
  • n'utilisez jamais l' opérateur -aor -o(utilisez plusieurs [commandes et les opérateurs shell &&et ||)

Faire [fiable avec des coquilles POSIX.

Pourquoi "ne jamais utiliser l' opérateur -aor -o"?

Comment puis-je "utiliser plusieurs [commandes et les opérateurs shell &&et ||)"?

Tim
la source

Réponses:

13

Pourquoi "ne jamais utiliser l' opérateur -aor -o"?

Parce qu'ils peuvent être ambigus et donc ils ne sont pas conformes à POSIX :

Les extensions XSI spécifiant les primaires binaires -a et -o et les opérateurs '(' et ')' ont été marquées comme obsolètes. (De nombreuses expressions les utilisant sont définies de manière ambiguë par la grammaire en fonction des expressions spécifiques évaluées.) Les scripts utilisant ces expressions doivent être convertis dans les formes indiquées ci-dessous. Même si de nombreuses implémentations continueront à prendre en charge ces formulaires obsolètes, les scripts doivent être extrêmement prudents lorsqu'ils traitent des entrées fournies par l'utilisateur qui pourraient être confondues avec ces éléments et d'autres primaires et opérateurs. À moins que le développeur de l'application ne connaisse tous les cas qui produisent une entrée pour le script, des invocations comme:

test "$1" -a "$2"

doit être écrit comme suit:

test "$1" && test "$2"

Comment puis-je "utiliser plusieurs [commandes et les opérateurs shell &&et ||)"?

En effectuant plusieurs tests et en les enchaînant à l'aide desdits opérateurs; par exemple:

[ 0 -eq 0 -a \( 0 -eq 1 -o 1 -eq 1 \) ]

pourrait être réécrit comme l'équivalent:

[ 0 -eq 0 ] && ([ 0 -eq 1 ] || [ 1 -eq 1 ])

ou mieux:

[ 0 -eq 0 ] && { [ 0 -eq 1 ] || [ 1 -eq 1 ]; }
kos
la source
Merci. (1) "les opérateurs '(' et ')' sont devenus obsolètes". Sont (et )les opérateurs qui regroupent les commandes? S'ils sont obsolètes, quel est leur remplacement? (2) Doit test "$1" -a "$2"être remplacé par test "$1" && test "$2"ou par ((test "$1" && test "$2"))? N'avons-nous pas besoin du ((..))?
Tim
@Tim Voir la mise à jour. (1) Oui - vous pouvez utiliser ()et {}en remplacement. (2) Le premier; (())est utilisé pour l'expansion arithmétique, ici vous voulez tester l'état de sortie de la chaîne de tests, donc regroupez les tests dans un sous-shell ()ou dans le shell actuel {}.
kos
Merci. Je pense que mes questions peuvent dépasser ce post. Je les poste donc dans un nouveau post.
Tim
1
@Tim La seule raison d'utiliser les opérateurs (et )est lorsque vous utilisez -aou -o. Les seconds étant obsolètes, les premiers ne sont évidemment plus nécessaires non plus.
Barmar