Forstå boolske operatører i bash-skript [duplikat]

Dette spørsmålet har allerede svar her :

Svar

Variabelen $phone_missing er en streng som tilfeldigvis inneholder false. Og en streng som ikke er tom, evalueres til true. Se også http://www.linuxintro.org/wiki/Babe#empty_strings

Kommentarer

  • Ah ok. Jeg ville ha erklært den variabelen som boolsk (i det minste ikke med erklæringsordet), men askekonsollen vant ' ikke la meg. Jeg vil ikke ' ikke sammenligne strenger. Hvordan gjøres dette riktig?
  • stackoverflow.com/questions/2953646/… , men vær forsiktig: denne fyren UTFØRER en strengvariabel, og like falsk som sant er unix-kommandoer.

Svar

Jeg bruker ofte «true» og «false» siden de også er kommandoer som bare gir henholdsvis suksess og fiasko. Da kan du gjøre

if "$phone_missing"; then ... 

Svar

Her er en måte å gjøre dette, mens du beholder de sanne / falske verdiene.

 phone_missing=false if [ "$phone_missing" != false ]; then echo "phone_missing is not "false" (but may be non-true, too)" fi if [ "$phone_missing" == true ]; then echo "phone_missing is true." fi  

Dobbel sitatene rundt $phone_missing skal beskytte mot saken der variabel phone_missing ikke er definert i det hele tatt. Et annet vanlig idiom å avverge mot dette er [ x$phone_missing != xfalse ], men sitatene virker mer naturlige for meg.

Hintet er i bash hjelpesiden for test:

 STRING True if string is not empty. ... ! EXPR True if expr is false. 

Så, i utgangspunktet vil [ $foo ] være sant hvis $foo ikke er tom. Ikke sant eller usant, bare ikke-tomt. [ ! $foo ] er sant hvis $ foo er tom eller udefinert.

Du kan alltid endre koden til å bare sette phone_missing til en ikke -fri verdi e, som vil betegne sant. Hvis phone_missing ikke er angitt (eller tomt – phone_missing=""), vil det være falskt. Ellers bør du bruke strengtestoperatørene (= og !=).

Det andre lille problemet er oppgaven. Du har det som $phone_missing=true, mens det skal være phone_missing=true (uten dollartegn).

Beklager hvis dette er litt tett, det er fordi jeg er. Det har vært en lang dag. 🙂

Svar

Andre svar ga deg løsning, men jeg vil forklare hva som var galt med den opprinnelige tenkningen.

Bash-variabler har ikke typer, så det er ikke noe som heter en boolsk variabel eller verdi som true eller false. I utgangspunktet er alle bash-variabler bare strenger.

Når du tester en variabel / streng i bash uten å spesifisere type test (-n eller -z), vil det som standard være en -n (ikke-null lengdestreng) test.

[ "$var" ] tilsvarer [ -n "$var" ]. Så lenge $var inneholder minst ett tegn, ble det evaluert til sant.

Siden du negerte uttrykket, [ ! "$var" ] tilsvarer [ ! -n "$var" ]. Så hvis $var inneholder minst ett tegn, så er uttrykket usant.

Siden false (som bare er en streng) inneholder 5 tegn, uttrykket er usant. Hvis det ikke betyr noe hvilken streng du setter phone_missing til (true, 0, 1), vil uttrykket alltid være false fordi det er phone_missing, er ikke null. Den eneste måten å gjøre det til true er phone_missing="" siden det er null lengde.

Svar

Ikke bruk streng for boolsk. Bruk heltall.

Input:

val=1 ((val)) && echo "true" || echo "false" val=0 ((val)) && echo "true" || echo "false" 

Output:

true false 

Kilde :

((uttrykk))

Uttrykket evalueres i henhold til reglene beskrevet nedenfor under ARITMETISK EVALUERING. Hvis verdien av uttrykket ikke er null, er returstatusen 0; ellers er returstatusen 1. Dette tilsvarer nøyaktig å la «uttrykk».

Svar

Jeg ville ha gjort dette som en kommentar for å støtte James Ko men hadde ikke representanten til å kommentere eller offentlig stemme.

Problemet her er at [] parentesene er en indikasjon for å gjøre en sammenligningstest, for eksempel verdi eller strenglikhet.

Strengens sannhet i bash for en tom streng er "" (tom streng) evalueres til falsk (returverdi 1) og hvilken som helst ikke tom streng «falsk» «sant «eller» bob «er onkelen din» vurderes til sant (returverdi 0).

Du kan bevise dette for deg selv med:

 if [ "foo" ]; then echo true is $?; else echo false is $?; fi 

$? ovenfor er en spesiell variabel som inneholder de siste kommandoene exit status (0 suksess, og hvilken som helst> 0 for feilkode) og vil sende true is 0. Du kan erstatte "foo" med alt du vil, og resultatet blir det samme, bortsett fra hvis du erstatter det med en tom streng "" eller "" i hvilket tilfelle den vil evaluere den andre tilstanden og sende ut false is 1.

Når du bruker [ ] parenteser den interne setningen som! $ phone_missing blir evaluert og returnerer deretter en 0 for true eller 1 for falsk til if-kontoen uttalelse. Siden braketten evaluerer streng- og verdisammenligning blir $ phone_missing først utvidet til den ikke tomme strengen «false», som blir evaluert av [] som ikke tom streng (eller sann) og deretter! inverterer resultatet som resulterer i at if-setningen får en falsk (eller returverdi 1), og den hopper over det betingede organet som utfører den andre setningen hvis den er tilstede.

Som James Ko sa, ville notasjonen være å bare passere variabel som holder din «boolske» til if-kontrolluttalelsen. Merk at i bash må en boolsk true og false være små bokstaver som i: bool_true = true bool_false = false Ethvert annet tilfelle vil vurder som strenger og ikke boolsk.

Så hvis du bruker eksemplet ditt og James Ko, ville det være:

phone_missing=false echo "missing $phone_missing" if ! $phone_missing then echo "Lost phone at $readabletime" $phone_missing=true fi 

eller som jeg foretrekker for lesbarhet (syntaktisk det samme og James Ko «s)

phone_missing=false echo "missing $phone_missing" if ( ! $phone_missing ); then echo "Lost phone at $readabletime" $phone_missing=true fi 

Andre svar som av Alexios er bokstavelig talt å sjekke strenginnholdet. Slik at noe av det følgende vil resultere i falskt:

phone_missing=false if [ "$phone_missing" != false ]; then echo "phone_missing is not "false" (but may be non-true, too)" fi if [ "$phone_missing" == true ]; then echo "phone_missing is not "false" (but may be non-true, too)" fi if [ "$phone_missing" == Bobs_your_uncle ]; then echo "phone_missing is not "false" (but may be non-true, too)" fi 

Svar

Riktig syntaks er if ! $bool; then [statements]; fi.

Eksempel:

bool=false if ! $bool; then echo "This is correct!" fi if [ ! $bool ]; then echo "This is wrong!" fi 

Utgang: This is correct!

Kommentarer

  • Det er en sannhetskjerne i svaret ditt, men mangler noen forklaring, det fører til mer forvirring enn det løser. Dessuten er det lite mer enn en repetisjon av et av de forrige svarene. Hvis du ikke vil at svaret ditt skal fjernes, kan du forklare hvorfor det er riktig.

Legg igjen en kommentar

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