Il semble que les deux signalent à BASH de commencer avec une autre commande suivant les symboles, mais y a-t-il une différence distincte ?
Réponses
Trop de publicités?Avec cette ligne:
command1 && command2
la commande2 sera exécutée si (et seulement si) la commande1 renvoie un statut de sortie zéro, tandis que dans cette ligne:
command1 ; command2
les deux commandes command1 et command2 seront exécutées quoi qu'il arrive. Le point-virgule vous permet de taper plusieurs commandes sur une seule ligne.
Vous pouvez essayer la différence vous-même :
-
ls /chemin/invalide && echo "bonjour!"
puisque /invalid/path n'existe pas, ls ne peut pas vous montrer la liste des répertoires. Il échouera avec un message d'erreur : "ls: /invalid/path: Aucun fichier ou dossier de ce type".
La deuxième moitié de la commande (echo "bonjour!") n'est même pas exécutée car la première moitié a échoué. -
ls /chemin/invalide ; echo "bonjour!"
Le même message d'erreur apparaît comme précédemment, mais cette fois, la deuxième partie est exécutée !
ls: /invalid/path: Aucun fichier ou dossier de ce type
bonjour!
Pourquoi est-ce utile ?
Supposez que vous vouliez extraire un fichier appelé archive.tar.gz
Vous pourriez 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 pas réessayer.
Mise à jour : J'ai ajouté un script pour mettre en évidence certaines des pièges possibles :
Comme personne d'autre n'a mentionné "||", je vais le faire
Mise à jour 2 : quelques modifications importantes ici
&& est comme un "puis" d'une instruction "si" qui répond à "vrai"
|| n'est PAS comme le "sinon" d'une instruction "si"...
|| est comme un "puis" d'une instruction "si" qui répond à "faux"
Plus spécifiquement, && teste la valeur de retour $? de l'instruction précédente la plus récemment exécutée et passe le contrôle à l'instruction ou au sous-shell immédiatement suivant le &&... il ne passe le contrôle que si $? est vrai.
|| est similaire, et est souvent vu après une instruction &&, mais il teste une valeur de retour fausse ($?) de l'instruction précédente la plus récemment exécutée... NTC!, Nota Bene! Notez bien!.... si l'instruction précédente est une instruction && qui renvoie false quand vous vous attendez à ce qu'elle soit vraie, alors || répondra au false, donc mélanger les deux sur la même ligne peut être risqué
Le point principal que j'essaie de faire est en relation avec une erreur que j'ai commise. c.-à-d.
## [[condition]] && A || B
n'est pas ne se comporte pas comme un ternaire de style C/C++. c.-à-d.
// (condition) ? A : B
Voir le script ci-dessous pour des exemples de résultats "inattendus" de "A"
Le test de base et l'instruction && et || doit être sur la même ligne...
Exécutez ce script pour voir où les choses peuvent mal tourner lors de l'utilisation de && et ||
L'instruction la plus récemment exécutée peut ne pas être celle que vous attendez..
[[ condition]] && echo Bonjour || echo Au revoir .... est généralement sûr,
car un echo bien formé renverra vrai.
mais que se passe-t-il si vous accédez à un fichier qui n'existe pas ?
#!/bin/bash
#
# "codes de retour attendus" signifie: censé se comporter comme un test de condition normale AND / OR
#
if [[ "$1" != "" ]] ; then exit $1; fi # appel récursif pour renvoyer une valeur $? arbitraire (décimale)
echo
echo 'test 1: Tous les codes de retour sont "comme prévu"'
echo ======
((1==1)) && echo " ((1==1)) rc=$? ..&&.. la condition est vraie" || echo " ((1==1)) rc=$? ..||.. la condition est fausse"
$0 0 && echo " \$0 0 rc=$? ..&&.. la condition est vraie" || echo " \$0 0 rc=$? ..||.. la condition est fausse"
((1!=1)) && echo " ((1!=1)) rc=$? ..&&.. la condition est vraie" || echo " ((1!=1)) rc=$? ..||.. la condition est fausse"
$0 1 && echo " \$0 1 rc=$? ..&&.. la condition est vraie" || echo " \$0 1 rc=$? ..||.. la condition est fausse"
echo
echo 'test 2: Maintenant introduisez quelques erreurs "inattendues" dans le premier des &&/|| couples'
echo ======
((1==1)) && (echo " ((1==1)) rc=$? ..&&.. la condition est vraie"; $0 1) || echo " ((1==1)) rc=$? ..||.. la condition est fausse"
$0 0 && (echo " \$0 0 rc=$? ..&&.. la condition est vraie"; $0 2) || echo " \$0 0 rc=$? ..||.. la condition est fausse"
((1!=1)) && (echo " ((1!=1)) rc=$? ..&&.. la condition est vraie"; $0 3) || echo " ((1!=1)) rc=$? ..||.. la condition est fausse"
$0 1 && (echo " \$0 1 rc=$? ..&&.. la condition est vraie"; $0 4) || echo " \$0 1 rc=$? ..||.. la condition est fausse"
echo
echo 'test 3: Changez maintenant l'ordre des instructions && et ||, en utilisant des codes de retour "comme prévu"'
echo ======
((1==1)) || echo " ((1==1)) rc=$? ..||.. la condition est vraie" && echo " ((1==1)) rc=$? ..&&.. la condition est fausse"
$0 0 || echo " \$0 0 rc=$? ..||.. la condition est vraie" && echo " \$0 0 rc=$? ..&&.. la condition est fausse"
((1!=1)) || echo " ((1!=1)) rc=$? ..||.. la condition est vraie" && echo " ((1!=1)) rc=$? ..&&.. la condition est fausse"
$0 1 || echo " \$0 1 rc=$? ..||.. la condition est vraie" && echo " \$0 1 rc=$? ..&&.. la condition est fausse"
echo
echo 'test 4: Avec l'ordre des instructions && et || toujours inversé, introduisez des erreurs "inattendues" dans le premier des &&/|| couple'
echo ======
((1==1)) && (echo " ((1==1)) rc=$? ..&&.. la condition est vraie"; $0 1) || echo " ((1==1)) rc=$? ..||.. la condition est fausse"
$0 0 && (echo " \$0 0 rc=$? ..&&.. la condition est vraie"; $0 2) || echo " \$0 0 rc=$? ..||.. la condition est fausse"
((1!=1)) && (echo " ((1!=1)) rc=$? ..&&.. la condition est vraie"; $0 3) || echo " ((1!=1)) rc=$? ..||.. la condition est fausse"
$0 1 && (echo " \$0 1 rc=$? ..&&.. la condition est vraie"; $0 4) || echo " \$0 1 rc=$? ..||.. la condition est fausse"
exit
- Réponses précédentes
- Plus de réponses