web-dev-qa-db-fra.com

Utilisation déroutante de && et || les opérateurs

Je parcourais un /etc/rc.d/init.d/sendmail fichier (je sais que ce n'est presque jamais utilisé, mais j'étudie pour un examen), et je suis devenu un peu confus au sujet du && et le || les opérateurs. J'ai lu où ils peuvent être utilisés dans des déclarations telles que:

if [ test1 ] && [ test2 ]; then
     echo "both tests are true"
Elif [ test1 ] || [ test2 ]; then
     echo "one test is true"
fi

Cependant, ce script affiche des instructions sur une seule ligne telles que:

[ -z "$SMQUEUE" ] && SMQUEUE="QUEUE"
[ -f /usr/sbin/sendmail ] || exit 0

Ceux-ci semblent utiliser le && et || opérateurs pour obtenir des réponses basées sur des tests, mais je n'ai pas pu fouiller la documentation concernant cette utilisation particulière de ces opérateurs. Quelqu'un peut-il expliquer ce que cela fait dans ce contexte particulier?

105
josh-cain

Le côté droit de && ne sera évalué que si l'état de sortie du côté gauche est nul (c'est-à-dire vrai). || est l'inverse: il n'évaluera le côté droit que si l'état de sortie du côté gauche est différent de zéro (c'est-à-dire faux).

Vous pouvez envisager [ ... ] pour être un programme avec une valeur de retour. Si le test à l'intérieur est évalué à vrai, il renvoie zéro; sinon, il renvoie différent de zéro.

Exemples:

$ false && echo howdy!

$ true && echo howdy!
howdy!
$ true || echo howdy!

$ false || echo howdy!
howdy!

Notes supplémentaires:

Si tu fais which [, vous pourriez voir que [ pointe en fait vers un programme! Ce n'est généralement pas en fait celui qui s'exécute dans les scripts; courir type [ pour voir ce qui est réellement exécuté. Si vous voulez essayer d'utiliser le programme, donnez simplement le chemin complet comme ceci: /bin/[ 1 = 1.

159
Shawn J. Goff

Voici ma feuille de triche:

  • "A; B" Exécutez A puis B, indépendamment du succès de A
  • "A && B" Exécutez B si A réussit
  • "A || B" Exécutez B si A a échoué
  • "A &" Exécutez A en arrière-plan.
67
user177073

pour développer la réponse de @ Shawn-j-Goff d'en haut, && est un ET logique, et || est un OU logique.

Voir this partie du Guide de script avancé Bash. Une partie du contenu du lien pour référence utilisateur comme ci-dessous.

&& AND

if [ $condition1 ] && [ $condition2 ]
#  Same as:  if [ $condition1 -a $condition2 ]
#  Returns true if both condition1 and condition2 hold true...

if [[ $condition1 && $condition2 ]]    # Also works.
#  Note that && operator not permitted inside brackets
#+ of [ ... ] construct.

|| OU

if [ $condition1 ] || [ $condition2 ]
# Same as:  if [ $condition1 -o $condition2 ]
# Returns true if either condition1 or condition2 holds true...

if [[ $condition1 || $condition2 ]]    # Also works.
#  Note that || operator not permitted inside brackets
#+ of a [ ... ] construct.
30
Tim Kennedy

D'après mon expérience, j'utilise les && et || pour réduire une instruction if sur une seule ligne.

Supposons que nous recherchons un fichier appelé /root/Sample.txt, l'itération traditionnelle serait la suivante dans Shell:

if [ -f /root/Sample.txt ]
then
    echo "file found"
else
    echo "file not found"
fi

Ces 6 lignes peuvent être réduites à une seule ligne:

[[ -f /root/Sample.txt ]] && echo "file found" || echo "file not found"

Lorsque vous exécutez quelques itérations pour définir des variables ou pour créer des fichiers, etc., la vie est plus facile et le script semble plus lisse en utilisant la seule ligne si la fonction, son seul inconvénient est qu'il devient un peu plus difficile d'implémenter plusieurs commandes à partir d'une seule itération cependant vous pouvez utiliser des fonctions.

13
syme89

Il existe une notion de "raccourci".

Quand (expr1 && expr2) est évalué - expr2 n'est évalué que si exp1 est évalué à "vrai". C'est parce que les deux expr1 ET expr2 doit être vrai pour (expr1 && expr2) pour être vrai. Si expr1 est évalué à "faux" expr2 n'est PAS évalué (raccourci) car (expr1 && expr2) est déjà "flase".

Essayez ce qui suit - supposez que le fichier F1 existe & fichier F2 n'existe pas:

( [ -s F1 ] && echo "File Exists" )  # will print "File Exists" - no short cut
( [ -s F2 ] && echo "File Exists" )  # will NOT print "File Exists" - short cut

De même pour || (ou) - mais la coupe courte est inversée.

4
Larry