Forvirrende brug af & & og || operatører

Jeg skumrede gennem en /etc/rc.d/init.d/sendmail -fil (jeg ved, at dette næsten aldrig er brugt, men jeg er studerer til en eksamen), og jeg er blevet lidt forvirret over operatørerne && og ||. Jeg har læst, hvor de kan bruges i udsagn som:

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

Dette script viser dog enkeltlinjesætninger som:

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

Disse ser ud til at bruge && og || til at fremkalde svar baseret på test, men jeg har ikke været i stand til at grave op dokumentation om netop denne brug af disse operatører. Kan nogen forklare, hvad disse gør i netop denne sammenhæng?

Svar

Højre side af && evalueres kun, hvis udgangsstatus for venstre side er nul (dvs. sand). || er det modsatte: det vil kun evaluere højre side, hvis status for venstre udgang ikke er nul (dvs. falsk).

Du kan overveje [ ... ] for at være et program med en returværdi. Hvis testen inden evalueres til sand, returnerer den nul; det returnerer ellers nul.

Eksempler:

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

Ekstra noter:

Hvis du gør which [, kan du se, at [ faktisk peger på et program! Det er dog som regel ikke den, der kører i scripts; kør type [ for at se, hvad der rent faktisk bliver kørt. Hvis du vil prøve at bruge programmet, skal du bare give den fulde sti som så: /bin/[ 1 = 1.

Kommentarer

  • Når du ser ” X eller Y “, tester du X. Hvis det ‘ er sandt, ved du allerede svaret på ” X eller Y ” (det ‘ er sandt), så det er ikke nødvendigt at teste Y. Hvis det ‘ er sandt, du kender ikke ‘ svaret på ” X eller Y “, så du skal teste Y. Når du ser ” X og Y ” , tester du X. Hvis det ‘ er forkert, ved du allerede svaret på ” X og Y ” (it ‘ er falsk), s ingen grund til at teste Y. Hvis X er sandt, skal du teste Y for at se om ” X og Y ” er sandt.
  • I stedet for ” hvis venstre side returnerer nul “, ville jeg skrive ” hvis kommandoen til venstre side ‘ s exit-status er nul “. Jeg finder ” return ” lidt tvetydig, da output og exit status begge kan betragtes som ” returnerer værdier ”
  • Ikke kun kan du ” overveje [ ... ] for at være et program “, i mange tilfælde er . Det ‘ er almindeligt i filen /bin/[ eller /usr/bin/[.
  • C-programmører finder dette super forvirrende. Der 0 betyder falsk … Mens i shellscript betyder 0 sandt … Mind blown.
  • @Calmarius Hvis du ‘ er vant til C, så tænk på return status, ikke booleanske, hvor return 0 betyder succes.

Svar

Her er mit snydeark:

  • “A; B “Kør A og derefter B, uanset succes A
  • ” A & & B “Kør B hvis A lykkedes
  • “A || B “Kør B, hvis A mislykkedes
  • ” A & “Kør A i baggrunden.

Kommentarer

  • Der ‘ er nogle interessante lambda-beregningsparalleller, der foregår her demonstreret i fungerende JavaScript (definer variablerne i rækkefølge); ” venstre (aka true) “: (a => b => a). ” højre (aka false) “: (a => b => b). ” A; B ” ” derefter ” (a => b => (() => b())(a())). ” A & & B ” ” hvis uden andet (når) ” (a => b => a()(() => right)(b)).” A || B ” ” andet uden hvis (medmindre) ” (a => b => a()(b)(() => right)). ” a & & b || c ” ” ifThenElse ” (a => b => c => (unless(when(a)(b))(c))()) .
  • bemærk, at i bash er venstre analog 0 / tom streng, højre analog er alt andet.
  • Hvad med en enkelt lodret bjælke?

Svar

for at udvide svaret på @ Shawn-j-Goff ovenfra, && er en logisk AND, og || er en logisk ELLER.

Se denne del af Advanced Bash Scripting Guide. Noget af indholdet fra linket til brugerhenvisning som nedenfor.

& & OG

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. 

|| ELLER

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. 

Svar

Fra min erfaring bruger jeg & & og d || for at reducere en if-sætning til en enkelt linje.

Sig, at vi leder efter en fil kaldet /root/Sample.txt, så vil den traditionelle iteration være som følger i shell:

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

Disse 6 linjer kan reduceres til en enkelt linje:

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

Når du kører et par iterationer for at indstille variabler eller for at oprette filer osv. er livet lettere og scriptet ser glattere ud ved hjælp af den enkelt linje hvis funktion, det er kun ulempen at det bliver lidt sværere at implementere flere kommandoer fra en enkelt iteration, men du kan gøre brug af funktioner.

Kommentarer

  • Dette er sejt. Mind mig om objc-kode (a == b)? val = 1: val = 2;
  • Hvordan kan jeg bruge denne kommando, når jeg vil køre en proces i baggrunden med ” & “? Jeg får en syntaksfejl for ./someScript.sh & && echo 'ok' || echo 'ko'
  • I form: foo && bar || baz, hvis foo lykkes, så bar mislykkes, baz køres, så det adskiller sig subtilt fra en if udsagn.
  • Jeg skal bemærke, at det er muligt at udføre flere kommandoer i en række i {} parenteser ved hjælp af && eller ||, såsom: pidof udpxy > /dev/null 2>&1 && echo "udpxy is up!" || { echo "udpxy is down!"; /etc/init.d/udpxy restart; }. Det er også værd at nævne, at if..then..else er en mere pålidelig ” genkender ” af true / falske forhold end at bruge && og ||.

Svar

Der er en forestilling om “genvej”.

Når (expr1 && expr2) vurderes – expr2 evalueres kun, hvis exp1 evalueres til” true “. Dette skyldes, at både expr1 OG expr2 skal være sandt for at (expr1 && expr2) skal være sandt. Hvis expr1 evalueres til “falsk”, expr2 IKKE evalueres (genvej), fordi (expr1 && expr2) er allerede “flase”.

Prøv følgende – antag, at filen F1 findes & -fil F2 findes ikke:

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

Tilsvarende for || (eller) – men kort klipning er omvendt.

Kommentarer

  • Logikken kaldes normalt ” kortslutning “. Jeg ‘ har aldrig set udtrykket ” genvej ” brugt. Jeg nævner dette for at hjælpe med at finde referencer.

Svar

Eksemplerne i svaret af Shawn J. Goff er korrekte, men forklaringen er omvendt. Kontroller venligst:

Højre side af & & vil kun blive evalueret, hvis udgangsstatus for venstre side er NONZERO. || er det modsatte: den evaluerer kun højre side, hvis status for venstre udgang er NUL.

Kommentarer

  • Du er opmærksom på, at for skaller nul udgangskode evalueres til sand og dermed ikke-nul udgangskode på venstre side af && resulterer i, at hele udtrykket returnerer false ?
  • Nogen godkendte ikke dine redigeringer, fordi det ikke var dit svar.Hvis du mener, at et eller andet svar er forkert, skal du nedstemme det og eventuelt efterlade en kommentar. hvis du mener, at det kræver en ændring, skal du efterlade en kommentar. Redigering er til at rette grammatik, formatering og stavefejl, der ikke ændrer betydningen af svaret.
  • @countermode I ‘ Jeg er ked af, du har ret, Jeg tænkte i Linux zero = false og nonzero = true (som i C og mange andre sprog / miljøer / platforme). Jeg undskylder for misforståelsen.

Skriv et svar

Din e-mailadresse vil ikke blive publiceret. Krævede felter er markeret med *