Forvirrende bruk av & & og || operatorer

Jeg skummet gjennom en /etc/rc.d/init.d/sendmail -fil (jeg vet at dette nesten ikke er brukt, men jeg «m studerer for en eksamen), og jeg har blitt litt forvirret om operatørene && og ||. Jeg har lest hvor de kan brukes i utsagn som:

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

Imidlertid viser dette skriptet enkeltlinjesetninger som:

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

Disse ser ut til å bruke operatørene && og || for å få svar basert på tester, men jeg har ikke vært i stand til å grave opp dokumentasjon om denne spesielle bruken av disse operatørene. Kan noen forklare hva disse gjør i denne spesielle sammenhengen?

Svar

Høyre side av && vil bare bli evaluert hvis utgangsstatusen til venstre er null (dvs. sant). || er det motsatte: det vil bare evaluere høyre side hvis utgangsstatus på venstre side ikke er null (dvs. usann).

Du kan vurdere [ ... ] for å være et program med en returverdi. Hvis testen inni vurderes til sant, returnerer den null; den returnerer ellers null.

Eksempler:

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

Ekstra merknader:

Hvis du gjør which [, kan du se at [ faktisk peker på et program! Det er som regel ikke den som kjører i skript, men kjør type [ for å se hva som faktisk blir kjørt. Hvis du vil prøve å bruke programmet, er det bare å gi hele banen som så: /bin/[ 1 = 1.

Kommentarer

  • Når du ser » X eller Y «, tester du X. Hvis det ‘ er sant, vet du allerede svaret på » X eller Y » (det ‘ er sant), så det er ikke nødvendig å teste Y. Hvis det ‘ sant, du vet ikke ‘ svaret på » X eller Y «, så du trenger å teste Y. Når du ser » X og Y » , tester du X. Hvis det ‘ er usant, vet du allerede svaret på » X og Y » (it ‘ er falskt), s o ikke behov for å teste Y. Hvis X er sant, trenger du å teste Y for å se om » X og Y » er sant.
  • I stedet for » hvis venstre side returnerer null «, vil jeg skrive » hvis kommandoen til venstre ‘ s utgangsstatus er null «. Jeg synes » returnerer » litt tvetydig da både utdata og utgangsstatus kan betraktes som » returnerer verdier »
  • Ikke bare kan du » vurdere [ ... ] for å være et program «, i mange tilfeller er . Det ‘ er ofte i filen /bin/[ eller /usr/bin/[.
  • C-programmerere vil synes dette er veldig forvirrende. Der 0 betyr falsk … Mens i shellscripting betyr 0 sant … Mind blown.
  • @Calmarius Hvis du ‘ er vant til C, tenk på return statuser, ikke booleans, der return 0 betyr suksess.

Svar

Her er mitt jukseark:

  • «A; B «Kjør A og deretter B, uansett suksess for A
  • » A & & B «Kjør B hvis A lyktes
  • «A || B «Kjør B hvis A mislyktes
  • » A & «Kjør A i bakgrunnen.

Kommentarer

  • Det ‘ er noen interessante lambda-beregningsparalleller som foregår her demonstrert i fungerende JavaScript (definer variablene i rekkefølge); » venstre (aka true) «: (a => b => a). » høyre (aka false) «: (a => b => b). » A; B » » deretter » (a => b => (() => b())(a())). » A & & B » » hvis uten annet (når) » (a => b => a()(() => right)(b)).» A || B » » annet uten hvis (med mindre) » (a => b => a()(b)(() => right)). » a & & b || c » » ifThenElse » (a => b => c => (unless(when(a)(b))(c))()) .
  • Vær oppmerksom på at i bash er venstre analog 0 / tom streng, høyre analog er alt annet.
  • Hva med en enkelt vertikal stolpe?

Svar

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

Se denne delen av Advanced Bash Scripting Guide. Noe av innholdet fra lenken for brukerreferanse 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 bruker jeg & & en d || for å redusere en if-setning til en enkelt linje.

Si at vi leter etter en fil som heter /root/Sample.txt, så vil den tradisjonelle iterasjonen være som følger i skall:

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

Disse 6 linjene kan reduseres til en enkelt linje:

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

Når du kjører noen iterasjoner for å angi variabler eller for å lage filer osv., livet er lettere og skriptet ser glattere ut ved å bruke den eneste linjen hvis funksjonen. Det er bare ulempen at det blir litt vanskeligere å implementere flere kommandoer fra en enkelt iterasjon, men du kan bruke funksjonene.

Kommentarer

  • Dette er kult. Minner meg om objc-kode (a == b)? val = 1: val = 2;
  • Hvordan kan jeg bruke denne kommandoen når jeg vil kjøre en prosess i bakgrunnen med » & «? Jeg får en syntaksfeil for ./someScript.sh & && echo 'ok' || echo 'ko'
  • I skjemaet: foo && bar || baz, hvis foo lykkes da bar mislykkes, baz kjøres, så det er subtilt forskjellig fra en if uttalelse.
  • Jeg må merke meg at det er mulig å utføre flere kommandoer på rad i {} parenteser ved hjelp av && eller ||, for eksempel: pidof udpxy > /dev/null 2>&1 && echo "udpxy is up!" || { echo "udpxy is down!"; /etc/init.d/udpxy restart; }. Det er også verdt å nevne at if..then..else er en mer pålitelig » gjenkjenning » av true / falske forhold enn å bruke && og ||.

Svar

Det er en forestilling om «snarvei».

Når (expr1 && expr2) vurderes – expr2 evalueres bare hvis exp1 evalueres til» true «. Dette er fordi både expr1 OG expr2 må være sant for at (expr1 && expr2) skal være sant. Hvis expr1 evalueres til «false», expr2 IKKE evalueres (snarvei) fordi (expr1 && expr2) er allerede «flase».

Prøv følgende – antag at filen F1 eksisterer & fil F2 eksisterer 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 skjæring er omvendt.

Kommentarer

  • Logikken blir vanligvis referert til som » kortslutning «. Jeg ‘ har aldri sett uttrykket » snarvei » brukt. Jeg nevner dette for å hjelpe til med å finne referanser.

Svar

Eksemplene i svaret av Shawn J. Goff er riktige, men forklaringen er omvendt. Vennligst sjekk:

Høyre side av & & vil bare bli evaluert hvis utgangsstatusen til venstre er NONZERO. || er det motsatte: den vil bare evaluere høyre side hvis utgangsstatus til venstre er NULL.

Kommentarer

  • Du er klar over at for skall null utgangskode evalueres til sann og dermed ikke null utgangskode på venstre side av && resulterer i at hele uttrykket returnerer false ?
  • Noen godkjente ikke endringene dine fordi det ikke var svaret ditt.Hvis du mener at noe svar er feil, bør du nedstemme det og eventuelt legge igjen en kommentar; Hvis du mener at det krever en endring, bør du legge igjen en kommentar. Redigering er for å korrigere grammatikk, formatering og stavefeil som ikke endrer betydningen av svaret.
  • @countermode I ‘ Beklager, du har rett, Jeg trodde i Linux zero = false og nonzero = true (som i C og mange andre språk / miljøer / plattformer). Jeg beklager misforståelsen.

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert. Obligatoriske felt er merket med *