577 votes

Quel est le meilleur : utiliser ; ou && pour exécuter plusieurs commandes sur une seule ligne ?

Dans les tutoriels et les didacticiels, je vois souvent des commandes combinées. Par exemple,

sudo apt-get update && sudo apt-get install pyrenamer

Il semble y avoir quatre connecteurs possibles : &, &&, || et ;. Bien que le connecteur & me soit clair (il envoie un processus en arrière-plan et laisse le terminal disponible), il n'est pas clair quelle est la différence entre && et ;. Et je ne connaissais pas || avant le commentaire de Kaya.

Les questions suivantes traitent de la différence entre les deux connecteurs, mais le font principalement dans les commentaires :

Voici donc plusieurs questions connexes :

  1. Quelle est la différence entre ; et && ?
  2. Quand devriez-vous les utiliser respectivement ? Ce serait bien de voir quelques cas d'utilisation : si je veux exécuter une commande puis éteindre mon ordinateur après, quel connecteur devrais-je choisir ?
  3. Quels sont leurs avantages et dangers ? Robie Basak mentionne dans un commentaire à cette réponse qu'une commande comme cd /somewhere_else; rm -Rf * peut avoir des conséquences destructrices si le premier élément de la chaîne de commandes échoue, par exemple.
  4. Si pertinent, d'où viennent-ils ?

1033voto

Jack Points 10346

Feuille de triche :

A; B    # Exécuter A puis B, indépendamment du succès de A
A && B  # Exécuter B seulement si A a réussi
A || B  # Exécuter B seulement si A a échoué
A &     # Exécuter A en arrière-plan.

89voto

John O'Brien Points 21

&& ne lance le second commande que si le premier a terminé avec le statut 0 (a réussi). ; exécute les deux commandes, même si le premier se termine avec un statut non nul.

Votre exemple avec && peut être paraphrasé de manière équivalente comme

si sudo apt-get update ; then
    sudo apt-get install pyrenamer
fi

39voto

Web-E Points 20948

En utilisant ;, les commandes seront exécutées indépendamment que la première commande soit réussie ou non.

En utilisant &&, la deuxième commande ne sera exécutée que si la première commande est exécutée avec succès (statut 0).

Tous deux sont utilisés d'un point de vue différent. Par exemple, pour un processus plus long, disons pour une installation, vous devez compiler et l'installer. Vous devriez utiliser make && make install. Donc, l'installation ne s'exécutera que si make a réussi.

Donc, pour des commandes dépendantes, vous devriez utiliser &&.

Pour des scripts bash, ou des commandes indépendantes, utilisez ;.

Donc, si vous voulez éteindre l'ordinateur même si le premier travail a échoué, utilisez ;, mais si vous voulez initier l'arrêt seulement en cas de succès complet du premier travail, utilisez &&.

17voto

ignis Points 4017

a ; b exécutera b quel que soit le statut de sortie de a. a && b exécutera b seulement si a a réussi.

Cela est nécessaire et suffisant pour répondre aux 3 premières questions. En particulier, la 2 est trop large et ne peut pas avoir "une" réponse définitive - le mieux est de décider au cas par cas.

Pour la 4ème question: Ce sont des syntaxes Bash.

Il n'y a aucun danger intrinsèque à les utiliser. Encore une fois, la définition ci-dessus est suffisante. Cela implique que vous écrirez && lorsque b a des effets non intentionnels si a ne réussit pas. Il n'y a pas besoin de règles ou d'explications supplémentaires, à mon avis.

9voto

davidxxx Points 191

La réponse de Jack est une très bonne règle empirique.

A; B    # Exécute A puis B, peu importe si A a réussi ou échoué
A && B  # Exécute B uniquement si A a réussi
A || B  # Exécute B uniquement si A a échoué
A &     # Exécute A en arrière-plan

J'ajouterais que dans certains cas, il peut être judicieux d'utiliser ces commandes dans un sous-shell lorsque nous voulons les considérer comme une unité unique ou que nous ne voulons pas lier le résultat de certaines opérations avec le shell actuel.

Exemples:

  • Concaténer la sortie de deux commandes:

    (ls foo; ls bar) > single-result.txt
  • Aller dans un répertoire et exécuter une commande à partir de là sans changer le répertoire actuel du shell:

    (cd target-directory && jar -xf ../my-jar)

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X