Y a-t-il une différence entre '&&' et ';' symboles dans un terminal BASH standard?

52

Ils semblent indiquer à BASH de commencer par une autre commande suivant les symboles, mais existe-t-il une différence nette?

    
posée Michael Terry 27.01.2011 - 18:01
la source

6 réponses

66

Avec cette ligne:

command1 && command2

commande2 sera exécuté si (et seulement si) commande1 renvoie le statut de sortie zéro, alors que dans cette ligne:

command1 ; command2

les commandes1 et commande2 seront exécutées indépendamment. Le point-virgule vous permet de saisir plusieurs commandes sur une même ligne.

    
réponse donnée user8290 27.01.2011 - 18:12
la source
40

Vous pouvez essayer la différence par vous-même:

  1. ls /invalid/path && echo "hello!"
    Puisque / invalid / path n'existe pas, ls ne peut pas vous montrer la liste des répertoires. Il échouera avec le message d'erreur suivant: "ls: / invalid / path: aucun fichier ou répertoire de ce type".
    La seconde moitié de la commande (echo "hello!") Est jamais exécutée car la première moitié a échoué.

  2. ls /invalid/path ; echo "hello!"
    Le même message d'erreur apparaît, mais cette fois-ci, la deuxième partie est exécutée !
    ls: / invalid / path: aucun fichier ou répertoire de ce type
    bonjour!

Pourquoi est-ce utile?
Supposons que vous souhaitiez extraire un fichier appelé archive.tar.gz

Vous pouvez utiliser la commande tar zxvf archive.tar.gz && rm archive.tar.gz .
Si pour une raison quelconque l'extraction de l'archive échoue, la deuxième partie n'est pas exécutée! Vous pouvez réessayer.

Si vous utilisez; dans la même situation, l’archive est supprimée et vous ne pouvez plus essayer.

    
réponse donnée Kenny Rasschaert 27.01.2011 - 18:37
la source
8

&& est AND , ce qui signifie que la deuxième commande ne sera exécutée que si la première a renvoyé la valeur true (aucune erreur).

    
réponse donnée Ward Muylaert 27.01.2011 - 18:11
la source
6

Mettre à jour : j'ai ajouté un script pour mettre en évidence certains des pièges possibles:

Parce que personne d'autre n'a mentionné "||", je le ferai

Mise à jour2 : quelques reformulations importantes ici
& & est comme un "alors" d'une "si" déclaration qui répond à "true"

|| est PAS comme le "sinon" d'une déclaration "si" ..
|| est comme un "alors" d'une "si" déclaration qui répond à "faux"

Plus spécifiquement, & & teste le $? renvoie la valeur de l'instruction précédente la plus récente et passe le contrôle à l'instruction ou au sous-shell immédiatement après le & & ... il ne passe le contrôle que si $? est vrai.

|| est similaire et est souvent observé après un & & déclaration, mais il recherche une fausse valeur de retour ($?) à partir de la précédente déclaration la plus récemment exécutée ... NB! , Nota Bene! Notez bien! .... si l'instruction précédente est un & & déclaration qui revient faux lorsque vous vous attendez à ce qu'elle soit vraie, puis || répondra au faux, donc mélanger les deux sur la même ligne peut être risqué

L’essentiel de mon propos est lié à une erreur que j’ai commise. c'est à dire:
 ## [[condition]] & & A || B
is not ne se comporte pas comme un ternaire de style C / C ++. c'est à dire:
// (condition)? A: B
Voir le script ci-dessous pour des exemples de résultats "inattendus" de "A"

Le test de base et les & & et le || déclaration doit être sur la même ligne ...

Exécutez ce script pour voir où des problèmes peuvent survenir lors de l'utilisation de & & et ||
La dernière instruction exécutée peut ne pas être celle que vous attendez.

[[condition]] & & echo Bonjour || echo Au revoir .... est typiquement en sécurité,
car un écho bien formé retournera vrai.
mais qu'en est-il de l'accès à un fichier qui n'existe pas?

#!/bin/bash
#
# "as expected" return codes" means: expected to behave like a normal AND / OR  contition test
#
if [[ "$1" != "" ]] ; then exit $1; fi # recursive call to return an arbitary $? value (decimal)
echo
echo 'test 1: All return codes are "as expected"'
echo  ======
 ((1==1)) && echo  " ((1==1)) rc=$? ..&&.. condition is true" || echo  " ((1==1)) rc=$? ..||.. condition is false"
  $0  0   && echo "  \
#!/bin/bash
#
# "as expected" return codes" means: expected to behave like a normal AND / OR  contition test
#
if [[ "$1" != "" ]] ; then exit $1; fi # recursive call to return an arbitary $? value (decimal)
echo
echo 'test 1: All return codes are "as expected"'
echo  ======
 ((1==1)) && echo  " ((1==1)) rc=$? ..&&.. condition is true" || echo  " ((1==1)) rc=$? ..||.. condition is false"
  $0  0   && echo "  \%pre%  0   rc=$? ..&&.. condition is true" || echo "  \%pre%  0   rc=$? ..||.. condition is false"
 ((1!=1)) && echo  " ((1!=1)) rc=$? ..&&.. condition is true" || echo  " ((1!=1)) rc=$? ..||.. condition is false"
  $0  1   && echo "  \%pre%  1   rc=$? ..&&.. condition is true" || echo "  \%pre%  1   rc=$? ..||.. condition is false"
echo
echo 'test 2: Now throw in some "unexpected" errors into the first of the &&/|| pair' 
echo  ======
 ((1==1)) && (echo  " ((1==1)) rc=$? ..&&.. condition is true"; $0 1)  || echo  " ((1==1)) rc=$? ..||.. condition is false"
  $0  0   && (echo "  \%pre%  0   rc=$? ..&&.. condition is true"; $0 2)  || echo "  \%pre%  0   rc=$? ..||.. condition is false"
 ((1!=1)) && (echo  " ((1!=1)) rc=$? ..&&.. condition is true"; $0 3)  || echo  " ((1!=1)) rc=$? ..||.. condition is false"
  $0  1   && (echo "  \%pre%  1   rc=$? ..&&.. condition is true"; $0 4)  || echo "  \%pre%  1   rc=$? ..||.. condition is false"
echo
echo 'test 3: Now swap the order of && and || statements, using "as expected" return codes'
echo  ======
 ((1==1)) || echo  " ((1==1)) rc=$? ..||.. condition is true" && echo  " ((1==1)) rc=$? ..&&.. condition is false"
  $0  0   || echo "  \%pre%  0   rc=$? ..||.. condition is true" && echo "  \%pre%  0   rc=$? ..&&.. condition is false"
 ((1!=1)) || echo  " ((1!=1)) rc=$? ..||.. condition is true" && echo  " ((1!=1)) rc=$? ..&&.. condition is false"
  $0  1   || echo "  \%pre%  1   rc=$? ..||.. condition is true" && echo "  \%pre%  1   rc=$? ..&&.. condition is false"
echo
echo 'test 4: With the order of && and || statements still swapped, introduce "unexpected" errors into the first of the &&/|| pair' 
echo  ======
 ((1==1)) && (echo  " ((1==1)) rc=$? ..&&.. condition is true"; $0 1)  || echo  " ((1==1)) rc=$? ..||.. condition is false"
  $0  0   && (echo "  \%pre%  0   rc=$? ..&&.. condition is true"; $0 2)  || echo "  \%pre%  0   rc=$? ..||.. condition is false"
 ((1!=1)) && (echo  " ((1!=1)) rc=$? ..&&.. condition is true"; $0 3)  || echo  " ((1!=1)) rc=$? ..||.. condition is false"
  $0  1   && (echo "  \%pre%  1   rc=$? ..&&.. condition is true"; $0 4)  || echo "  \%pre%  1   rc=$? ..||.. condition is false"

exit 
0 rc=$? ..&&.. condition is true" || echo " \%pre% 0 rc=$? ..||.. condition is false" ((1!=1)) && echo " ((1!=1)) rc=$? ..&&.. condition is true" || echo " ((1!=1)) rc=$? ..||.. condition is false" $0 1 && echo " \%pre% 1 rc=$? ..&&.. condition is true" || echo " \%pre% 1 rc=$? ..||.. condition is false" echo echo 'test 2: Now throw in some "unexpected" errors into the first of the &&/|| pair' echo ====== ((1==1)) && (echo " ((1==1)) rc=$? ..&&.. condition is true"; $0 1) || echo " ((1==1)) rc=$? ..||.. condition is false" $0 0 && (echo " \%pre% 0 rc=$? ..&&.. condition is true"; $0 2) || echo " \%pre% 0 rc=$? ..||.. condition is false" ((1!=1)) && (echo " ((1!=1)) rc=$? ..&&.. condition is true"; $0 3) || echo " ((1!=1)) rc=$? ..||.. condition is false" $0 1 && (echo " \%pre% 1 rc=$? ..&&.. condition is true"; $0 4) || echo " \%pre% 1 rc=$? ..||.. condition is false" echo echo 'test 3: Now swap the order of && and || statements, using "as expected" return codes' echo ====== ((1==1)) || echo " ((1==1)) rc=$? ..||.. condition is true" && echo " ((1==1)) rc=$? ..&&.. condition is false" $0 0 || echo " \%pre% 0 rc=$? ..||.. condition is true" && echo " \%pre% 0 rc=$? ..&&.. condition is false" ((1!=1)) || echo " ((1!=1)) rc=$? ..||.. condition is true" && echo " ((1!=1)) rc=$? ..&&.. condition is false" $0 1 || echo " \%pre% 1 rc=$? ..||.. condition is true" && echo " \%pre% 1 rc=$? ..&&.. condition is false" echo echo 'test 4: With the order of && and || statements still swapped, introduce "unexpected" errors into the first of the &&/|| pair' echo ====== ((1==1)) && (echo " ((1==1)) rc=$? ..&&.. condition is true"; $0 1) || echo " ((1==1)) rc=$? ..||.. condition is false" $0 0 && (echo " \%pre% 0 rc=$? ..&&.. condition is true"; $0 2) || echo " \%pre% 0 rc=$? ..||.. condition is false" ((1!=1)) && (echo " ((1!=1)) rc=$? ..&&.. condition is true"; $0 3) || echo " ((1!=1)) rc=$? ..||.. condition is false" $0 1 && (echo " \%pre% 1 rc=$? ..&&.. condition is true"; $0 4) || echo " \%pre% 1 rc=$? ..||.. condition is false" exit
réponse donnée Peter.O 09.02.2011 - 07:42
la source
1

essayer

false && echo "hello"

et

false ; echo "hello"

voir la différence

    
réponse donnée Petrie Wong 09.02.2011 - 07:19
la source
0

La commande (fonction, dans le cas d'un script) après && est exécutée en fonction du RETVAL de la première commande (fonction, dans le cas d'un script). Il force la première commande à renvoyer une valeur de 0 en cas de succès. Nous pouvons vérifier la valeur de retour pour exécuter d'autres commandes.

    
réponse donnée theTuxRacer 09.02.2011 - 09:07
la source

Lire d'autres questions sur les étiquettes