GNU/Linux >> Tutoriels Linux >  >> Linux

Plusieurs opérateurs logiques, ((a || B) &&C), et "Erreur de syntaxe proche d'un jeton inattendu" ?

Je travaille avec Bash 3 et j'essaie de former un conditionnel. En C/C++, c'est très simple :((A || B) && C) . Dans Bash, ce n'est pas le cas (je pense que les auteurs de Git ont dû contribuer à ce code avant de passer à d'autres projets).

Cela ne fonctionne pas. Notez que <0 or 1> n'est pas un littéral de chaîne ; cela signifie un 0 ou un 1 (vient généralement de grep -i ).

A=<0 or 1>
B=<0 or 1>
C=<0 or 1>
if [ [ "$A" -eq "0" ] || [ "$B" -ne "0" ] ] && [ "$C" -eqe "0" ]; then ... fi

Il en résulte :

line 322: syntax error near unexpected token `[['

J'ai alors essayé :

A=<0 or 1>
B=<0 or 1>
C=<0 or 1>
if [ ([ "$A" -eq "0" ]) || ([ "$B" -ne "0" ]) ] && [ "$C" -eq "0" ]; then ... fi

il en résulte :

line 322: syntax error near unexpected token `[['

Une partie du problème est que les résultats de recherche sont des exemples triviaux, et non des exemples plus complexes avec des conditions composées.

Comment effectuer un simple ((A || B) && C) dans Bash ?

Je suis prêt à le dérouler et à répéter les mêmes commandes dans plusieurs blocs :

A=<0 or 1>
B=<0 or 1>
C=<0 or 1>

if [ "$A" -eq "0" ] && [ "$C" -eq "0" ]; then
    ...
elif [ "$B" -ne "0" ] && [ "$C" -eq "0" ]; then
    ... 
fi

Réponse acceptée :

La syntaxe de bash n'est pas du type C, même si une petite partie est inspirée du C. Vous ne pouvez pas simplement essayer d'écrire du code C et vous attendre à ce qu'il fonctionne.

Le point principal d'un shell est d'exécuter des commandes. La commande entre parenthèses ouvertes [ est une commande qui effectue un seul test¹. Vous pouvez même l'écrire comme test (sans la parenthèse fermante finale). Le || et && les opérateurs sont des opérateurs shell, ils combinent des commandes , pas des tests.

Alors quand vous écrivez

[ [ "$A" -eq "0" ] || [ "$B" -ne "0" ] ] && [ "$C" -eq "0" ]

qui est analysé comme

[ [ "$A" -eq "0" ] ||
[ "$B" -ne "0" ] ] &&
[ "$C" -eq "0" ]

qui est identique à

test [ "$A" -eq "0" ||
test "$B" -ne "0" ] &&
test "$C" -eq "0"

Remarquez les parenthèses déséquilibrées ? Ouais, ce n'est pas bon. Votre tentative avec des parenthèses a le même problème :de fausses parenthèses.

La syntaxe pour regrouper les commandes est les accolades. La façon dont les accolades sont analysées nécessite une commande complète avant elles, vous devrez donc terminer la commande à l'intérieur des accolades avec une nouvelle ligne ou un point-virgule.

if { [ "$A" -eq "0" ] || [ "$B" -ne "0" ]; } && [ "$C" -eq "0" ]; then …

Il existe une autre méthode qui consiste à utiliser des doubles parenthèses. Contrairement aux parenthèses simples, les parenthèses doubles sont une syntaxe shell spéciale. Ils délimitent les expressions conditionnelles. À l'intérieur des doubles parenthèses, vous pouvez utiliser des parenthèses et des opérateurs comme && et || . Étant donné que les doubles crochets sont une syntaxe shell, le shell sait que lorsque ces opérateurs sont entre crochets, ils font partie de la syntaxe de l'expression conditionnelle, et non de la syntaxe de commande shell ordinaire.

if [[ ($A -eq 0 || $B -ne 0) && $C -eq 0 ]]; then …

Si tous vos tests sont numériques, il y a encore un autre moyen, qui délimite les expressions artihmétiques. Les expressions arithmétiques effectuent des calculs d'entiers avec une syntaxe très proche du C.

if (((A == 0 || B != 0) && C == 0)); then …

Vous trouverez peut-être mon introduction au support bash utile.

Connexe :Debian – Crash du système – caractères étranges dans syslog ?

[ peut être utilisé en sh uni. [[ et (( sont spécifiques à bash (et ksh et zsh).

¹ Il peut également combiner plusieurs tests avec des opérateurs booléens, mais c'est lourd à utiliser et comporte des pièges subtils, donc je ne l'expliquerai pas.


Linux
  1. Priorité des opérateurs logiques Shell &&, ||?

  2. Piège, erreur et écho de la ligne d'erreur ?

  3. Ssh vers plusieurs hôtes et exécuter une commande ?

  4. "Erreur de syntaxe près d'un jeton inattendu" après la modification de .bashrc ?

  5. Configuration et réglage d'OpenVAS dans Kali Linux

Comment Grep pour plusieurs chaînes et modèles

Comment installer et configurer plusieurs moteurs d'échecs sur XBoard

Sauvegarde et restauration d'instantanés LVM sous Linux

Explication :Redirection des entrées, des sorties et des erreurs sous Linux

Erreur de syntaxe près du jeton inattendu 'then'

IPv6 et NAT, routage vers plusieurs FAI