Exécutez deux commandes en cas de || ou &&

11

J'ai lu sur && et || et je voudrais exécuter deux commandes dans le faux cas.

J'ai essayé ;mais ça marche toujours . J'ai essayé de le mettre entre accolades, { command1; command2 }mais cela entraîne une erreur de syntaxe.

Je veux faire quelque chose comme

command && echo "Ok, continuing" || echo "Check internet connection"; exit 1

qui n'est fermé que s'il n'y a pas de connexion Internet.

Thomas Weller
la source
1
Cela ressemble à une simple erreur typographique. Une question beaucoup plus intéressante à poser est la différence entre ()et {}.
edwinksl

Réponses:

27

L'utilisation de parens met les commandes dans un sous-shell qui n'est pas toujours ce que vous voulez. Vous pouvez également utiliser des accolades:

command && echo "Ok, continuing" || { echo "Check internet connection"; exit 1; }

L'astuce ici est que, contrairement aux parens, la commande finale entre accolades doit être suivie de ;.

Pourquoi un point-virgule ou une nouvelle ligne est requis

Une accolade est un argument valide pour une commande. Par exemple, voici une accolade comme un argument pour echo:

$ echo }
}

Par conséquent, si le shell voit:

{ command1; command2 }

Le shell interprète command1 comme n'ayant aucun argument et command2 comme ayant un argument composé du caractère }. Une accolade }n'est interprétée comme fermant un regroupement que si elle suit un point-virgule ou une nouvelle ligne. Pour faire fonctionner ce qui précède:

{ command1; command2; }

Sous-coques et la différence entre {...}et(...)

Notez que les valeurs suivantes sont définies xsur 10 mais que ce paramètre est oublié avant l' echoexécution de la commande:

$ x=0; false || ( echo Hello; x=10 )
Hello
$ echo $x
0

Avec les accolades, en revanche, le réglage de x=10est rappelé:

$ x=0; false || { echo Hello; x=10; }
Hello
$ echo $x
10

La différence est due au fait que les affectations de variables dans un sous-shell ne survivent pas une fois le sous-shell terminé.

Documentation

De man bash:

(liste)

La liste est exécutée dans un environnement de sous-shell (voir ENVIRONNEMENT D'EXÉCUTION DE COMMANDE ci-dessous). Les affectations de variables et les commandes intégrées qui affectent l'environnement du shell ne restent pas en vigueur une fois la commande terminée. Le statut de retour est le statut de sortie de la liste.

{ liste; }

La liste est simplement exécutée dans l'environnement shell actuel. la liste doit se terminer par une nouvelle ligne ou un point-virgule. C'est ce qu'on appelle une commande de groupe. Le statut de retour est le statut de sortie de la liste. Notez que contrairement aux métacaractères (et), {et} sont des mots réservés et doivent se produire lorsqu'un mot réservé est autorisé à être reconnu. Comme ils ne provoquent pas de rupture de mot, ils doivent être séparés de la liste par des espaces ou un autre métacaractère shell.

[Italiques ajoutés]

John1024
la source