Utilizarea confuză a & & și || operatori

Parcurgeam un fișier /etc/rc.d/init.d/sendmail (știu că acest lucru nu este folosit niciodată, dar „m studiez pentru un examen) și am devenit un pic confuz cu privire la && și la operatorii ||. Am „citit unde pot fi utilizate în afirmații precum:

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

Cu toate acestea, acest script prezintă afirmații cu o singură linie, cum ar fi:

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

Acestea par să utilizeze operatorii && și || pentru a obține răspunsuri pe baza teste, dar nu am reușit să descopăr documenarea cu privire la această utilizare specială a acestor operatori. Poate cineva să explice ce fac acestea în acest context particular?

Răspunde

Partea dreaptă a && va fi evaluat numai dacă starea de ieșire din partea stângă este zero (adică adevărat). || este opusul: va evalua partea dreaptă numai dacă starea de ieșire din partea stângă este diferită de zero (adică falsă).

Puteți lua în considerare [ ... ] să fie un program cu o valoare returnată. Dacă testul din interior se evaluează la adevărat, acesta returnează zero; se întoarce altfel decât zero.

Exemple:

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

Note suplimentare:

Dacă faceți which [, ați putea vedea că [ indică de fapt un program! De obicei, nu este de fapt cel care rulează în scripturi, totuși; rulați type [ pentru a vedea ce se execută de fapt. Dacă doriți să încercați să utilizați programul, pur și simplu dați calea completă ca deci: /bin/[ 1 = 1.

Comentarii

  • Când vedeți ” X sau Y „, testați X. Dacă este ‘ adevărat, știți deja răspunsul la ” X sau Y ” (este ‘ adevărat), deci nu este nevoie să testați Y. Dacă este ‘ este adevărat, nu ‘ nu știți răspunsul la ” X sau Y „, deci trebuie să testați Y. Când vedeți ” X și Y ” , testați X. Dacă ‘ este fals, știți deja răspunsul la ” X și Y ” (it ‘ este fals), s o nu este nevoie să testați Y. Dacă X este adevărat, trebuie să testați Y pentru a vedea dacă ” X și Y ” este adevărat.
  • În loc de ” dacă partea stângă returnează zero „, aș scrie ” dacă starea de ieșire a comenzii din partea stângă ‘ este zero „. Mi se pare ” return ” un pic ambiguu, deoarece ieșirea și starea de ieșire pot fi considerate ambele ca ” returnează valorile ”
  • Nu numai că poți ” lua în considerare [ ... ] să fie un program „, în multe cazuri este . ‘ este în mod obișnuit în fișierul /bin/[ sau /usr/bin/[.
  • Programatorii C vor găsi acest lucru foarte confuz. 0 înseamnă fals … În timp ce în shellscripting 0 înseamnă adevărat … Minte suflată.
  • @Calmarius Dacă ‘ sunteți obișnuit cu C, gândiți-vă la div id = „9ce9f13bea”>

stări, nu booleeni, undereturn 0înseamnă succes.

Răspuns

Aici este foaia mea de înșelăciune:

  • „A; B „Executați A și apoi B, indiferent de succesul lui A
  • ” A & & B „Executați B dacă A a reușit
  • „A || B „Rulați B dacă A eșuați
  • ” A & „Rulați A în fundal.

Comentarii

  • Există ‘ câteva paralele de calcul lambda interesante care au loc aici, demonstrate în JavaScript de lucru (definiți variabilele în ordine); ” stânga (aka true) „: (a => b => a). ” dreapta (aka fals) „: (a => b => b). ” A; B ” ” apoi ” (a => b => (() => b())(a())). ” A & & B ” ” dacă fără altceva (când) ” (a => b => a()(() => right)(b)).” A || B ” ” altul fără if (dacă nu) ” (a => b => a()(b)(() => right)). ” a & & b || c ” ” ifThenElse ” (a => b => c => (unless(when(a)(b))(c))()) .
  • rețineți că în bash, stânga este analog 0 / șir gol, dreapta analog este orice altceva.
  • Dar o singură bară verticală?

Răspuns

pentru a extinde răspunsul de la @ Shawn-j-Goff de sus, && este un AND logic și || este un OR logic.

Consultați această parte a Advanced Bash Scripting Guide. Unele dintre conținuturile din link pentru referința utilizatorului, ca mai jos.

& & ȘI

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. 

|| SAU

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ăspuns

Din experiența mea, folosesc & & d || pentru a reduce o instrucțiune if la o singură linie.

Spuneți că căutăm un fișier numit /root/Sample.txt atunci iterația tradițională ar fi următoarea în shell:

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

Aceste 6 linii pot fi reduse la o singură linie:

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

Când rulați câteva iterații pentru a seta variabile sau pentru a crea fișiere etc., viața este mai ușoară și scriptul arată mai ușor folosind linia unică dacă funcția, singurul dezavantaj este că devine puțin mai dificil să implementați mai multe comenzi dintr-o singură iterație, cu toate acestea puteți utiliza funcțiile.

Comentarii

  • Este grozav. Îmi amintește codul objc (a == b)? val = 1: val = 2;
  • Cum pot folosi această comandă atunci când vreau să rulez un proces în fundal cu ” & „? Primesc o eroare de sintaxă pentru ./someScript.sh & && echo 'ok' || echo 'ko'
  • În forma: foo && bar || baz, dacă foo reușește, atunci bar eșuează, baz va fi rulat, deci este subtil diferit de un if declarație.
  • Trebuie să rețin că este posibil să executați mai multe comenzi la rând între {} paranteze, folosind && sau ||, cum ar fi: pidof udpxy > /dev/null 2>&1 && echo "udpxy is up!" || { echo "udpxy is down!"; /etc/init.d/udpxy restart; }. De asemenea, merită menționat faptul că if..then..else este un recunoscător ” mai fiabil ” al true / condiții false decât utilizarea && și ||.

Răspuns

Există o noțiune de „scurtare”.

Când (expr1 && expr2) este evaluat – expr2 este evaluat numai dacă exp1 este evaluat la” adevărat „. Aceasta deoarece atât expr1, cât și expr2 trebuie să fie adevărate pentru ca (expr1 && expr2) să fie adevărate. Dacă expr1 se evaluează la „fals” expr2 NU este evaluat (scurtătură) deoarece (expr1 && expr2) este deja „flase”.

Încercați următoarele – presupuneți că fișierul F1 există & fișier F2 nu există:

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

Similar pentru || (sau) – dar scurt tăierea este inversată.

Comentarii

  • Logica este denumită de obicei ” scurtcircuit „. ‘ nu am văzut niciodată folosită fraza ” tăiere scurtă „. Menționez acest lucru pentru a ajuta la găsirea referințelor.

Răspuns

Exemplele din răspunsul lui Shawn J. Goff sunt corecte, dar explicația este invers. Vă rugăm să verificați:

Partea dreaptă a & & va fi evaluat numai dacă starea de ieșire din partea stângă este NONZERO. || este opusul: va evalua partea dreaptă numai dacă starea de ieșire din partea stângă este ZERO.

Comentarii

  • Sunteți conștient de faptul că, pentru shell-uri, codul de ieșire zero se evaluează ca adevărat și, astfel, codul de ieșire diferit de din partea stângă a && are ca rezultat întreaga expresie pentru a returna false ?
  • Cineva nu v-a aprobat modificările deoarece nu a fost răspunsul dvs.Dacă credeți că un răspuns este incorect, ar trebui să îl votați negativ și, eventual, să lăsați un comentariu; dacă credeți că necesită o schimbare, ar trebui să lăsați un comentariu. Editarea este pentru corectarea greșelilor gramaticale, de formatare și de ortografie care nu schimbă sensul răspunsului.
  • @countermode Îmi pare ‘ îmi pare rău, ai dreptate, M-am gândit în Linux zero = false și nonzero = true (ca în C și multe alte limbi / medii / platforme). Îmi cer scuze pentru neînțelegere.

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *