Verwarrend gebruik van & & en || operators

Ik was aan het bladeren door een /etc/rc.d/init.d/sendmail -bestand (ik weet dat dit bijna nooit wordt gebruikt, maar ik “m studeren voor een examen), en ik “ben een beetje in de war geraakt over de && en de || operators. Ik heb gelezen waar ze kunnen worden gebruikt in uitspraken zoals:

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

Dit script toont echter uitspraken van één regel zoals:

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

Deze lijken de && en || operators te gebruiken om reacties op te wekken op basis van tests, maar ik heb geen documentatie kunnen opgraven over dit specifieke gebruik van deze operators. Kan iemand uitleggen wat deze in deze specifieke context doen?

Antwoord

De rechterkant van && wordt alleen geëvalueerd als de uitgangsstatus van de linkerkant nul is (dwz waar). || is het tegenovergestelde: het evalueert de rechterkant alleen als de uitgangsstatus aan de linkerkant niet nul is (dwz false).

U kunt overwegen [ ... ] om een programma te zijn met een retourwaarde. Als de test binnenin true oplevert, retourneert het nul; anders geeft het niet-nul terug.

Voorbeelden:

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

Extra opmerkingen:

Als u which [, je zou kunnen zien dat [ daadwerkelijk naar een programma verwijst! Het is echter meestal niet degene die in scripts wordt uitgevoerd; voer type [ uit om te zien wat er daadwerkelijk wordt uitgevoerd. Als je het programma wilt proberen, geef dan het volledige pad op, zoals dus: /bin/[ 1 = 1.

Reacties

  • Als je ” X of Y “, je test X. Als het ‘ waar is, weet je al het antwoord op ” X of Y ” (het is ‘ s waar), dus u hoeft Y niet te testen. ‘ s waar, je ‘ weet niet het antwoord op ” X of Y “, dus u moet Y testen. Als u ” X en Y ” ziet , test je X. Als het ‘ onwaar is, weet je het antwoord al op ” X en Y ” (het ‘ s false), s o u hoeft Y niet te testen. Als X waar is, moet u Y testen om te zien of ” X en Y ” is waar.
  • In plaats van ” als de linkerkant nul retourneert “, zou ik als de linkeropdracht ‘ s exit-status nul is “. Ik vind ” return ” een beetje dubbelzinnig, aangezien de uitvoer en de exit-status beide kunnen worden beschouwd als ” waarden retourneren ”
  • U kunt niet alleen ” overwegen [ ... ] om een programma te zijn “, in veel gevallen is . Het ‘ staat gewoonlijk in het bestand /bin/[ of /usr/bin/[.
  • C-programmeurs zullen dit super verwarrend vinden. Daar betekent 0 false … Terwijl in shellscripting 0 true betekent … Mind Blown.
  • @Calmarius Als je ‘ gewend bent aan C, denk dan aan return statussen, niet booleans, waarbij return 0 succes betekent.

Antwoord

Hier is mijn spiekbriefje:

  • “A; B “Voer A en vervolgens B uit, ongeacht het succes van A
  • ” A & & B “Run B als A is geslaagd
  • “A || B “Voer B uit als A mislukt
  • ” A & “Voer A uit op de achtergrond.

Opmerkingen

  • Er zijn ‘ s enkele interessante lambda-calculus parallellen die hier worden gedemonstreerd in JavaScript (definieer de variabelen in volgorde); ” links (ook bekend als true) “: (a => b => a). ” right (ook bekend als false) “: (a => b => b). ” A; B ” ” en vervolgens ” (a => b => (() => b())(a())). ” A & & B ” ” if zonder else (when) ” (a => b => a()(() => right)(b)).” A || B ” ” anders zonder if (tenzij) ” (a => b => a()(b)(() => right)). ” a & & b || c ” ” ifThenElse ” (a => b => c => (unless(when(a)(b))(c))()) .
  • merk op dat in bash, links analoog 0 / lege string is, rechts analoog al het andere.
  • Hoe zit het met een enkele verticale balk?

Antwoord

om het antwoord van @ Shawn-j-Goff van bovenaf uit te breiden, && is een logische AND, en || is een logische OR.

Zie dit deel van de Advanced Bash Scripting Guide. Een deel van de inhoud van de link voor gebruikersreferentie, zoals hieronder.

& & EN

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. 

|| OF

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. 

Antwoord

Uit mijn ervaring gebruik ik de & & een d || om een if-statement te reduceren tot een enkele regel.

Stel dat we op zoek zijn naar een bestand met de naam /root/Sample.txt, dan zou de traditionele iteratie in shell als volgt zijn:

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

Deze 6 regels kunnen worden teruggebracht tot een enkele regel:

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

Bij het uitvoeren van enkele iteraties om variabelen in te stellen of om bestanden enz. aan te maken, is het leven gemakkelijker en ziet het script er gelikter uit met de enkele regel if-functie, het enige nadeel is dat het een beetje moeilijker wordt om meerdere commandos uit een enkele iteratie te implementeren, maar je kunt wel gebruik maken van functies.

Reacties

  • Dit is cool. Doet me denken aan objc-code (a == b)? val = 1: val = 2;
  • Hoe kan ik deze opdracht gebruiken als ik een proces op de achtergrond wil uitvoeren met ” & “? Ik krijg een syntaxisfout voor ./someScript.sh & && echo 'ok' || echo 'ko'
  • In de vorm: foo && bar || baz, if foo slaagt dan bar mislukt, baz wordt uitgevoerd, dus het verschilt subtiel van een if statement.
  • Ik moet opmerken dat het mogelijk is om verschillende commandos achter elkaar uit te voeren in {} haakjes, met && of ||, zoals: pidof udpxy > /dev/null 2>&1 && echo "udpxy is up!" || { echo "udpxy is down!"; /etc/init.d/udpxy restart; }. Het is ook vermeldenswaard dat if..then..else een betrouwbaardere ” herkenner ” van true / is valse voorwaarden dan het gebruik van && en ||.

Antwoord

Er is een idee van “short cut”.

Wanneer (expr1 && expr2) wordt geëvalueerd – expr2 wordt alleen geëvalueerd als exp1 evalueert naar” true “. Dit komt doordat expr1 EN expr2 waar moeten zijn om (expr1 && expr2) waar te maken. Als expr1 evalueert naar “false”, expr2 NIET wordt geëvalueerd (snelkoppeling) omdat (expr1 && expr2) is al “flase”.

Probeer het volgende – neem aan dat bestand F1 bestaat & bestand F2 bestaat niet:

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

Evenzo voor || (of) – maar kort snijden is omgekeerd.

Opmerkingen

  • De logica wordt meestal aangeduid als ” kortsluiting “. Ik ‘ heb de zin ” short cut ” nog nooit gebruikt. Ik noem dit om te helpen bij het vinden van referenties.

Antwoord

De voorbeelden in het antwoord door Shawn J. Goff kloppen, maar de uitleg is andersom. Controleer het volgende:

De rechterkant van & & wordt alleen geëvalueerd als de uitgangsstatus van de linkerkant NONZERO is.is het tegenovergestelde: het evalueert de rechterkant alleen als de uitgangsstatus aan de linkerkant NUL is.

Reacties

  • U bent zich ervan bewust dat voor shells nul exitcode resulteert in true en dus niet-nul exitcode aan de linkerkant van && resulteert erin dat de hele uitdrukking false retourneert?
  • Iemand heeft uw bewerkingen niet goedgekeurd omdat het niet uw antwoord was.Als u denkt dat een of ander antwoord onjuist is, moet u het naar beneden stemmen en eventueel een opmerking achterlaten; als u denkt dat het een wijziging vereist, moet u een opmerking achterlaten. Bewerken is bedoeld voor het corrigeren van grammatica-, opmaak- en spelfouten die de betekenis van het antwoord niet veranderen.
  • @countermode I ‘ m sorry, je hebt gelijk, Ik dacht in Linux zero = false en nonzero = true (zoals in C en vele andere talen / omgevingen / platforms). Mijn excuses voor het misverstand.

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *