À quoi sert «&&» dans une commande shell?

Réponses:

399

&&vous permet de faire quelque chose selon que la commande précédente s'est terminée avec succès - c'est pourquoi vous avez tendance à la voir enchaînée comme do_something && do_something_else_that_depended_on_something.

girasquid
la source
391

De plus, vous avez également ||qui est le ou logique, et ;qui n'est qu'un séparateur qui ne se soucie pas de ce qui est arrivé à la commande précédente.

$ false || echo "Oops, fail"
Oops, fail

$ true || echo "Will not be printed"
$  

$ true && echo "Things went well"
Things went well

$ false && echo "Will not be printed"
$

$ false ; echo "This will always run"
This will always run

Quelques détails à ce sujet peuvent être trouvés ici Listes de commandes dans le manuel de Bash.

plundra
la source
5
Vous aimeriez peut-être ajouter false && echo "Will not be printed".
MTSan
112

ligne de commande - quel est le but de &&?

En coquille, quand vous voyez

$ command one && command two

l'intention est d'exécuter la commande qui suit &&uniquement si la première commande réussit. C'est idiomatique des coquilles Posix, et pas seulement dans Bash.

Il vise à empêcher l'exécution du deuxième processus si le premier échoue.

Vous remarquerez peut-être que j'ai utilisé le mot «intention» - c'est pour une bonne raison. Tous les programmes n'ont pas le même comportement, donc pour que cela fonctionne, vous devez comprendre ce que le programme considère comme un "échec" et comment il le gère en lisant la documentation et, si nécessaire, le code source.

Votre shell considère une valeur de retour de 0 pour true, d'autres nombres positifs pour false

Les programmes renvoient un signal à la sortie. Ils doivent retourner 0 s'ils sortent avec succès, ou supérieur à zéro s'ils ne le font pas. Cela permet une quantité limitée de communication entre les processus.

Le &&est appelé AND_IFdans la grammaire du shell posix , qui fait partie d'une and_orliste de commandes, qui incluent également le ||qui est un OR_IFavec une sémantique similaire.

Symboles de grammaire, cités dans la documentation:

%token  AND_IF    OR_IF    DSEMI
/*      '&&'      '||'     ';;'    */

Et la grammaire (également citée dans la documentation), qui montre que n'importe quel nombre de AND_IFs ( &&) et / ou OR_IFs ( ||) peut être enchaîné (comme and_ordéfini de manière récursive):

and_or           :                         pipeline
                 | and_or AND_IF linebreak pipeline
                 | and_or OR_IF  linebreak pipeline

Les deux opérateurs ont la même priorité et sont évalués de gauche à droite (ils sont associatifs à gauche). Comme le disent les docs:

Une AND-ORliste est une séquence d'un ou plusieurs pipelines séparés par les opérateurs "&&"et "||".

Une liste est une séquence d'un ou plusieurs ET-OU listes séparées par les opérateurs ';'et '&'et éventuellement terminé par ';', '&'ou.

Les opérateurs "&&"et "||"ont même priorité et doivent être évalués avec associativité à gauche. Par exemple, les deux commandes suivantes écrivent uniquement la barre sur la sortie standard:

$ false && echo foo || echo bar
$ true || echo foo && echo bar
  1. Dans le premier cas, le faux est une commande qui se termine avec le statut 1

    $ false
    $ echo $?
    1

    ce qui signifie echo foone fonctionne pas (c'est-à-dire court-circuitage echo foo). Ensuite, la commande echo barest exécutée.

  2. Dans le second cas, les vraies sorties avec un code de 0

    $ true
    $ echo $?
    0

    et echo foon'est donc pas exécuté, puis echo barest exécuté.

Aaron Hall
la source
31

Une utilisation assez courante pour «&&» est la compilation de logiciels avec des outils automatiques. Par exemple:

./configure --prefix=/usr && make && sudo make install

Fondamentalement, si la configuration réussit, make est exécuté pour être compilé, et si cela réussit, make est exécuté en tant que root pour installer le programme. J'utilise ceci lorsque je suis presque sûr que les choses fonctionneront, et cela me permet de faire d'autres choses importantes comme regarder stackoverflow et ne pas «surveiller» la progression.

Parfois je m'emporte vraiment ...

tar xf package.tar.gz && ( cd package; ./configure && make && sudo make install ) && rm package -rf

Je le fais quand par exemple faire un linux à partir de zéro.

Nigel Atkinson
la source
2
Bon en REPL, mais pour les scripts je préférerais set -o errexitpour Bash.
Franklin Yu
19

&&chaînes de commandes ensemble. Les commandes successives ne s'exécutent que si les précédentes réussissent.

De même, ||permettra à la commande successive de s'exécuter si la précédente échoue.

Voir Programmation Bash Shell .

Dean Burge
la source
8

Voir l'exemple:

mkdir test && echo "Something" > test/file

Shell essaiera de créer un répertoire testet ensuite, seulement s'il a réussi , essaiera de créer un fichier à l'intérieur.

Vous pouvez donc interrompre une séquence d'étapes si l'une d'elles échoue.

alno
la source
8

Il s'agit d'exécuter une deuxième instruction si la première instruction se termine avec succès. Comme une instruction if:

 if (1 == 1 && 2 == 2)
  echo "test;"

Son premier essai si 1 == 1, si c'est vrai, il vérifie si 2 == 2

pseudo
la source
1
Quelqu'un pourrait-il expliquer pourquoi cela a été rejeté pour les utilisateurs tombant sur la question?
user3243242
1
@ user3243242 ce n'est pas faux, juste un mauvais exemple pour illustrer l'utilisation de&&
dan
C'est un excellent aperçu du fonctionnement des iftests dans bash. Je n'y ai jamais pensé comme une chaîne de commandes de comparaison, se cassant quand l'une d'elles échouait. Vous avez donc mon vote positif :)
PiRK
1
La conséquence est que vous pouvez obtenir le comportement opposé en utilisant ||, pour enchaîner les commandes jusqu'à ce que l'une d'elles réussisse: eei || leu || uie || echo prout3 || echo "never executed"
PiRK
7

command_1 && command_2: exécuter command_2 uniquement lorsque command_1 est exécuté avec succès.

command_1 || command_2: exécuter command_2 uniquement lorsque command_1 n'a pas été exécuté avec succès.

Cela ressemble à la façon dont une condition «si» est exécutée dans un langage de programmation traditionnel, comme dans if (condition_1 && condition_2){...}condition_2 sera omise si condition_1 est falseet dans if (condition_1 || condition_2){...}condition_2 sera omise si condition_1 l'est true. Vous voyez, c'est la même astuce que vous utilisez pour le codage :)

Xiaonin Li
la source
Je ne sais pas ce que vous entendez par «exactement le contraire», mais $ echo «1» || echo '2' imprime seulement '1'. et $ false_command || echo '2' affiche un message d'erreur et '2' sur la ligne suivante. Pourriez-vous expliquer un peu plus ce qui, selon vous, est mauvais à ce sujet?
Xiaonin Li
ho mec, j'étais certainement trop fatigué hier. désolé pour cela, c'était seulement moi: / J'ai besoin que vous éditiez quelque chose dans votre réponse si vous voulez que j'augmente (pour rendre votre réponse 0, pour le moment stackoverflow demande la modification afin que je ne puisse pas)
Arount
@Arount, c'est ok ne vous inquiétez pas. Je viens donc de soumettre une modification. êtes-vous en mesure de supprimer le vote négatif maintenant?
Xiaonin Li
oui, encore une fois, désolé, vraiment
Arount
0
####################### && or (Logical AND) ######################
first_command="1"
two_command="2"

if [[ ($first_command == 1) && ($two_command == 2)]];then
 echo "Equal"
fi

Lorsque le programme vérifie si la commande, alors le programme crée un nombre appelé code de sortie, si les deux conditions sont vraies, le code de sortie est zéro (0), sinon, le code de sortie est un nombre positif. uniquement lors de l'affichage Égal si le code de sortie est généré zéro (0), cela signifie que les deux conditions sont vraies.

Amin
la source
Bienvenue sur stackoverflow. Veuillez vous assurer que votre extrait de code fonctionne avant de publier ici. Vous devez le corrigerif [[ ($first_command == "1") && ($two_command == "2") ]];then echo "Equal"; fi
Zheng Qu
1
Merci @ZhengQu pour ta commande, c'est fait.
Amin