Comment chaîner des commandes sur la console?

23

Dans bash, je souhaite parfois exécuter plusieurs commandes en série et ne pas attendre qu'elles se terminent avant de taper les nouvelles. Je fais donc quelque chose comme ça:

cmd1; cmd2; cmd3

Malheureusement, l'une des commandes peut échouer. Dans ce cas, j'aimerais m'arrêter. Y a-t-il un moyen facile de le faire, mais faites en sorte que je ne continue à exécuter les commandes que si la commande précédente avait un code de sortie 0?

métaphore pythonique
la source
Voici une excellente réponse de l'Unix SE.
NonlinearFruit

Réponses:

39

Utiliser l' &&opérateur,

cmd1 && cmd2 && cmd3

En shellscripting, &&et les ||opérateurs sont modélisés après la mise en œuvre optimisée des opérateurs logiques C. &&moyens et opérateur, et des ||moyens OU. Unix est étroitement lié à C, et en C, le deuxième opérande d'opérateurs logiques n'est pas évalué si le résultat est déjà connu du premier opérande. Par exemple, "false && x"c'est falsepour tout x, il n'y a donc pas besoin d'évaluer x(surtout s'il xs'agit d'un appel de fonction); de même pour "true || x". Ceci est également appelé sémantique de court-circuit .

Et sous Unix, il est traditionnel d'interpréter les valeurs de retour des commandes comme des valeurs de vérité "réussite terminée": le code de sortie 0 signifie true(succès), différent de zéro false(échec). Ainsi, lorsque la première commande cmd1 && cmd2retourne "false"(état de sortie différent de zéro, qui indique l'échec), l'état de la commande composée est connu: échec. L'interprétation globale de cmd1 && cmd2 peut donc être: "exécuter cmd1, ET ALORS, si cela n'a pas échoué cmd2". C'est ce que vous voulez essentiellement dans votre question.

De même avec OR: cmd1 || cmd2peut être interprété comme "exécuter cmd1, OU en cas d'échec cmd2".


Protip: pour des chaînes plus longues &&, pensez à mettre set -evotre script. Il change fondamentalement le point-virgule ;en &&, avec quelques cas spéciaux.

ulidtko
la source
1
+1 pour l'explication||
Alp
pouvez-vous enchaîner quel que soit le statut de la première commande? (succès ou échec)
Hugo Trentesaux
@HugoTrentesaux que voulez-vous dire? .. Le résultat de la réussite / échec ou A || Best exactement le même que le [court-circuitage] A OU B logique . A || Best le succès quand a Aété le succès , ou quand a Aété l' échec mais a Bété le succès ; et A || Bc'est l' échec quand Aétait l' échec et l' Bétait failure. De même pour &&, il suit un ET logique.
ulidtko
Dans le contexte du shell, comment puis-je exécuter A puis B, peu importe si A échoue ou réussit?
Hugo Trentesaux
1
@HugoTrentesaux, c'est ce que fait le plain regular ;(ou newline) par défaut. set -eva se transformer ;en &&gros. set +e[la valeur par défaut] se transforme A; Ben ce que vous dites: exécuter A, puis exécuter n'importe quoi B.
ulidtko
13

"Enchaîner les commandes et les regrouper"

ping 192.168.0.1 || { echo "ping not successful"; exit 1; }

pings, uniquement en cas d'échec, exécute le groupe chaîné de commandes entre crochets.

Attention:

La liste doit se terminer par un ";".

Il doit y avoir des espaces vides entre les crochets et les commandes groupées!

et moi
la source
6

Simplement avec l' &&opérateur. Par exemple:

cmd1 && cmd2 && cmd3

Si l'une des commandes échoue (renvoie une valeur de sortie autre que 0), les autres commandes ne s'exécuteront pas.

Wuffers
la source