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


Dans les tutoriels et les procédures, 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 est clair pour moi (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 savais pas de || jusqu'à ce que Kaya commente.

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

Voici donc un certain nombre de 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 et ensuite après avoir éteint mon ordinateur, quel connecteur devrais-je choisir?
  3. Quels sont leurs avantages et les dangers? Robie Basak mentionne dans un commentaire à cette réponse qu'une commande comme cd /somewhere_else; rm -Rf * peut avoir des conséquences destructives si le premier élément de la chaîne de commande échoue, par exemple.
  4. Si pertinent, d'où viennent-ils?

331
2017-08-20 16:41


origine


Il y a un autre connecteur que vous n'avez peut-être pas rencontré: ||est le même que && sauf qu'il n'exécute que la deuxième commande si la première est sortie avec un statut non nul (non réussi). - Kaya
Notez également que l'exécution de votre script avec set -e arrêtera le script en cas d'échec, comme si toutes les commandes étaient connectées avec &&. - choroba
stackoverflow.com/questions/3573742/… - Ciro Santilli 新疆改造中心 六四事件 法轮功
Personne n'a répondu à Qn 4 ... Je soupçonne le comportement de && et || a été inspiré par le langage de programmation C Dans le cas de (x && y), si x est évalué à false, l'expression entière doit être fausse afin qu'un compilateur puisse optimiser l'évaluation de y, au cas où cela serait coûteux. Les standards modernes C et C ++ en fait exiger cette optimisation, les programmes peuvent donc supposer que y ne sera pas évalué si x est faux. Par exemple, (ptr && ptr-> days> 31) ne se bloquera pas même si ptr est nul. Toujours en C, les déclarations se terminent par; qu'il y ait ou non une autre déclaration sur la même ligne. - Kevin


Réponses:


Cheatsheet:

A; B    # Run A and then B, regardless of success of A
A && B  # Run B if and only if A succeeded
A || B  # Run B if and only if A failed
A &     # Run A in background.

606
2017-10-20 11:02



Et bien sûr, A & B &: Exécutez A en arrière-plan, puis exécutez B en arrière-plan (quel que soit le succès) et renvoyez le contrôle au shell. Cela fonctionne souvent à peu près la même chose que l'exécution des deux processus en même temps. - Limited Atonement
est-il possible de dire: exécuter un en arrière-plan, suivi de b en arrière-plan seulement si cela a fonctionné? ( J'imagine &&& ?) - user230910
@ user230910: ce serait (A && B) &. - leftaroundabout
Pouvez-vous référencer un document faisant autorité pour cela? - Jaime Hablutzel
@Jack Lorsqu'il est exécuté à partir de Cronjob, il ne suit pas tout à fait cette règle, aucune idée de pourquoi? Pour un fichier python - CodeGuru


&& ne lance que la deuxième commande si la première est sortie avec le statut 0 (réussi). ; exécute les deux commandes, même si la première se termine avec un statut non nul.

Votre exemple avec && peut être paraphrasé comme

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

77
2017-08-20 16:46



Merci. J'ai mis à jour la question pour que les différentes sous-questions puissent être facilement distinguées. - don.joey
@ Privé: vous devriez utiliser ; si la seconde commande n'a pas besoin de la précédente pour réussir. - choroba


En utilisant ; exécutera les commandes indépendamment du fait que la première commande soit réussie ou non.

en utilisant && exécuter la deuxième commande uniquement lorsque la première commande est exécutée avec succès (statut 0).

Les deux sont utilisés dans des perspectives différentes. Comme pour un processus plus long, par exemple, pour une installation, vous devez la compiler et l'installer. vous devriez make && make install. Donc, l'installation ne fonctionnera que si make réussi.

Donc, pour les commandes dépendantes, vous devez utiliser &&

Écriture de bash, ou commandes avec des commandes indépendantes ; 

Donc, si vous souhaitez arrêter l'ordinateur, même le premier travail a échoué à utiliser ; , mais si vous le souhaitez sur le succès complet du premier travail, lancez l’utilisation de l’arrêt &&


28
2017-08-20 16:50



Merci. J'aime le dernier cas d'utilisation que vous présentez. J'ai mis à jour la question. - don.joey


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

Ceci est nécessaire et suffisant pour répondre aux 3 premières questions. En particulier, le 2 est trop large et on ne peut pas lui donner "une" réponse définitive - votre meilleur pari est de décider au cas par cas.

Quant à la 4ème question: Ils sont la syntaxe Bash.

Il n'y a pas de danger intrinsèque à utiliser l'un ou l'autre. Encore une fois, la définition ci-dessus est suffisante. Cela implique que vous allez écrire && quand b a des effets inattendus si a ne réussit pas. Il n'y a pas besoin de règles ou d'explications supplémentaires, à mon humble avis.


13
2017-08-20 21:05