Utilisation confuse de & & et || opérateurs

Je parcourais un fichier /etc/rc.d/init.d/sendmail (je sais que ce nest presque jamais utilisé, mais je « m étudiant pour un examen), et je suis devenu un peu confus au sujet des opérateurs && et ||. Jai lu où ils peuvent être utilisés dans des instructions 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 les opérateurs && et || pour obtenir des réponses basées sur tests, mais je n « ai pas pu déterrer de documentation concernant cette utilisation particulière de ces opérateurs. Quelquun peut-il expliquer ce quils font dans ce contexte particulier?

Réponse

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

Vous pouvez considérer [ ... ] pour être un programme avec une valeur de retour. Si le test à lintérieur est évalué à vrai, il renvoie zéro; sinon elle renvoie une valeur différente de zéro.

Exemples:

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

Notes supplémentaires:

Si vous faites which [, vous verrez peut-être que [ pointe effectivement vers un programme! Cependant, ce n’est généralement pas celui qui s’exécute dans les scripts; exécutez type [ pour voir ce qui est réellement exécuté. Si vous souhaitez essayer d’utiliser le programme, indiquez simplement le chemin complet comme donc: /bin/[ 1 = 1.

Commentaires

  • Lorsque vous voyez  » X ou Y « , vous testez X. Si ‘ est vrai, vous connaissez déjà la réponse à  » X ou Y  » (il ‘ est vrai), donc pas besoin de tester Y. Si cest ‘ est vrai, vous ‘ ne connaissez pas la réponse à  » X ou Y « , vous devez donc tester Y. Lorsque vous voyez  » X et Y  » , vous testez X. Si ‘ est faux, vous connaissez déjà la réponse à  » X et Y  » (il ‘ est faux), s o pas besoin de tester Y. Si X est vrai, alors vous devez tester Y pour voir si  » X et Y  » est true.
  • Au lieu de  » si le côté gauche renvoie zéro « , jécrirais  » si létat de sortie de la commande de gauche ‘ est égal à zéro « . Je trouve  » return  » un peu ambigu car la sortie et létat de sortie peuvent tous deux être considérés comme  » valeurs de retour  »
  • Non seulement vous pouvez  » prendre en compte [ ... ] pour être un programme « , dans de nombreux cas, il est . Il ‘ est généralement dans le fichier /bin/[ ou /usr/bin/[.
  • Les programmeurs C trouveront cela très déroutant. Là 0 signifie faux … Alors quen shellscripting 0 signifie vrai … Lesprit est époustouflé.
  • @Calmarius Si vous ‘ êtes habitué à C, pensez à return statuts, pas booléens, où return 0 signifie succès.

Réponse

Voici mon aide-mémoire:

  • « A; B « Exécuter A puis B, quel que soit le succès de A
  •  » A & & B « Exécution B si A réussit
  • « A || B « Exécuter B si A échoue
  •  » A & « Exécuter A en arrière-plan.

Commentaires

  • Il y a ‘ quelques parallèles de calcul lambda intéressants qui se déroulent ici démontrés dans JavaScript fonctionnel (définissez les variables dans lordre);  » gauche (aka true) « : (a => b => a).  » droite (aka false) « : (a => b => b).  » A; B  »  » puis  » (a => b => (() => b())(a())).  » A & & B  »  » si sans autre (quand)  » (a => b => a()(() => right)(b)). » A || B  »  » else sans if (sauf)  » (a => b => a()(b)(() => right)).  » a & & b || c  »  » ifThenElse  » (a => b => c => (unless(when(a)(b))(c))()) .
  • notez que dans bash, la gauche est analogue 0 / chaîne vide, la droite analogue est tout le reste.
  • Et une seule barre verticale?

Réponse

pour développer la réponse de @ Shawn-j-Goff « ci-dessus, && est un ET logique, et || est un OU logique.

Voir cette partie du Guide de script Bash avancé. Certains des contenus 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. 

Réponse

Daprès mon expérience, jutilise & & un d || pour réduire une instruction if à une seule ligne.

Supposons que nous recherchions un fichier appelé /root/Sample.txt, alors litération traditionnelle serait la suivante dans le 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" 

Lors de lexécution de 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 fonction if à une seule ligne, le seul inconvénient est quil devient un peu plus difficile dimplémenter plusieurs commandes à partir dune seule itération, mais vous pouvez utiliser des fonctions.

Commentaires

  • Cest cool. Cela me rappelle le code objc (a == b)? val = 1: val = 2;
  • Comment puis-je utiliser cette commande lorsque je souhaite exécuter un processus en arrière-plan avec  » & « ? Jobtiens une erreur de syntaxe pour ./someScript.sh & && echo 'ok' || echo 'ko'
  • Sous la forme: foo && bar || baz, si foo réussit alors bar échoue, baz sera exécuté, donc il est subtilement différent dun if instruction.
  • Je dois noter quil est possible dexécuter plusieurs commandes daffilée entre parenthèses {}, en utilisant && ou ||, comme: pidof udpxy > /dev/null 2>&1 && echo "udpxy is up!" || { echo "udpxy is down!"; /etc/init.d/udpxy restart; }. Il convient également de mentionner que if..then..else est un identificateur  »  » plus fiable de true / fausses conditions que dutiliser && et ||.

Réponse

Il existe une notion de « raccourci ».

Lorsque (expr1 && expr2) est évalué – expr2 nest évalué que si exp1 est évalué à » vrai « . En effet, les deux expr1 ET expr2 doivent être vrais pour que (expr1 && expr2) soit vrai. Si expr1 donne la valeur « false » expr2 nest PAS évalué (raccourci) car (expr1 && expr2) est déjà « flase ».

Essayez ce qui suit – supposons que le fichier F1 existe & fichier F2 nexiste 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 court la coupe est inversée.

Commentaires

  • La logique est généralement appelée  » court-circuitage « . Je ‘ n’ai jamais vu l’expression  » raccourci  » utilisée. Je mentionne cela pour aider à trouver des références.

Réponse

Les exemples de la réponse de Shawn J. Goff sont correctes, mais lexplication est linverse. Veuillez vérifier:

Le côté droit de & & ne sera évalué que si létat de sortie du côté gauche est NONZERO. || est le contraire: il névaluera le côté droit que si létat de sortie du côté gauche est ZERO.

Commentaires

  • Vous savez que pour les shells zéro le code de sortie s’évalue à true et donc le code de sortie différent de zéro sur le côté gauche de && renvoie lexpression entière à renvoyer false ?
  • Quelquun na pas approuvé vos modifications car ce nétait pas votre réponse.Si vous pensez quune réponse est incorrecte, vous devez la rejeter et éventuellement laisser un commentaire; si vous pensez que cela nécessite un changement, vous devriez laisser un commentaire. Lédition sert à corriger les fautes de grammaire, de mise en forme et dorthographe qui ne changent pas la signification de la réponse.
  • @countermode I ‘ désolé, vous avez raison, Jai pensé dans Linux zéro = faux et non zéro = vrai (comme en C et dans de nombreux autres langages / environnements / plates-formes). Je mexcuse pour le malentendu.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *