Forståelse af booleske operatører i bash-script [duplikat]

Dette spørgsmål har allerede svar her :

Svar

Variablen $phone_missing er en streng, der tilfældigvis indeholder false. Og en ikke-streng streng evalueres til true. Se også http://www.linuxintro.org/wiki/Babe#empty_strings

Kommentarer

  • Ah okay. Jeg ville have erklæret denne variabel som boolsk (i det mindste ikke med erklæringsordet), men askekonsollen vandt ikke '. Jeg vil heller ikke ' ikke sammenligne strenge. Hvordan gøres det rigtigt?
  • stackoverflow.com/questions/2953646/… , men pas på: denne fyr UDFØRER en strengvariabel, og såvel falsk som sand er unix-kommandoer.

Svar

Jeg bruger ofte “sand” og “falsk”, da de også er kommandoer, der kun returnerer henholdsvis succes og fiasko. Så kan du gøre

if "$phone_missing"; then ... 

Svar

Her er en måde at gøre dette, mens du opretholder de sande / falske værdier.

 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  

Dobbeltcitaterne omkring $phone_missing skal beskytte mod det tilfælde, hvor variabel phone_missing slet ikke er defineret. Et andet almindeligt idiom at afværge imod dette er [ x$phone_missing != xfalse ], men citaterne virker mere naturlige for mig.

Hintet er i bash hjælpesiden til test:

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

Så grundlæggende vil [ $foo ] være sandt, hvis $foo er ikke-tom. Ikke sandt eller falsk, bare ikke-tomt. [ ! $foo ] er sandt, hvis $ foo er tom eller udefineret.

Du kan altid ændre din kode til bare at indstille phone_missing til en ikke -fri værdi e, hvilket vil betegne sandt. Hvis phone_missing ikke er indstillet (eller tomt – phone_missing=""), er det forkert. Ellers skal du bruge strengtestoperatorerne (= og !=).

Det andet lille problem er Opgaven. Du har det som $phone_missing=true, mens det skal være phone_missing=true (intet dollartegn).

Undskyld, hvis dette er lidt tæt, det er fordi jeg er. Det har været en lang dag. 🙂

Svar

Andre svar gav dig løsning, men jeg vil forklare, hvad der var galt med den originale tænkning.

Bash-variabler har ikke typer, så der er ikke sådan en boolsk variabel eller værdi som sand eller falsk. Dybest set er alle bash-variabler kun strenge.

Når du tester en variabel / streng i bash uden at angive testtypen (-n eller -z), det er som standard en -n (ikke-nul længdestreng) test.

[ "$var" ] svarer til [ -n "$var" ]. Så længe $var indeholder mindst 1 tegn, blev det evalueret til sandt.

Da du benægtede udtrykket, [ ! "$var" ] svarer til [ ! -n "$var" ]. Så hvis $var indeholder mindst 1 tegn, er udtrykket falsk.

Da false (hvilket bare er en streng) indeholder 5 tegn, udtrykket er falsk. Hvis der ikke betyder noget, hvilken streng du indstiller phone_missing til (true, 0, 1), vil udtrykket altid være false fordi phone_missing er uden nul længde. Den eneste måde at gøre det til true er phone_missing="" da det er nul længde.

Svar

Brug ikke streng til boolsk. Brug heltal.

Input:

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

Output:

true false 

Kilde :

((udtryk))

Udtrykket evalueres i henhold til reglerne beskrevet nedenfor under ARITMETISK EVALUERING. Hvis udtrykkets værdi ikke er nul, er returstatus 0; ellers er returstatus 1. Dette svarer nøjagtigt til let “udtryk”.

Svar

Jeg ville have gjort dette som en kommentar til støtte for James Ko, men havde ikke rep til at kommentere eller stemme offentligt.

Problemet her er, at [] parenteserne er en betegnelse for at foretage en sammenligningstest som værdi eller strenglighed.

Sandhedens sandhed i bash for en tom streng er "" (tom streng) evalueres til falsk (returværdi 1) og enhver ikke tom streng “falsk” “sand “eller” bob “din onkel” vurderes til sand (returværdi 0).

Du kan bevise dette for dig selv med:

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

$? ovenfor er en speciel variabel, der indeholder de sidste kommandoer exit status (0 succes og enhver> 0 for fejlkode) og vil output true is 0. Du kan erstatte "foo" med alt hvad du vil, og resultatet bliver det samme, undtagen hvis du erstatter det med en tom streng "" eller "" i hvilket tilfælde den evaluerer den anden tilstand og output false is 1.

Når du bruger [ ] parenteser den interne sætning såsom! $ phone_missing evalueres og returnerer derefter en 0 for true eller 1 for falsk til if-kontoen Jeg erklærer. Da parentes evaluerer streng- og værdisammenligning, udvides $ phone_missing først til den ikke-tomme streng “false”, som evalueres af [] som ikke-tom streng (eller sand) og derefter! inverterer resultatet, hvilket resulterer i, at if-udsagnet får en falsk (eller returværdi 1), og det springer over det betingede organ, der udfører den anden erklæring, hvis den er til stede.

Som James Ko sagde, ville notationen være at bare passere variabel, der holder din “boolske” til if-kontroludtalelsen. Bemærk at i bash skal en boolsk sand og falsk være små bogstaver som i: bool_true = true bool_false = false Alle andre tilfælde vil evaluer som strenge og ikke boolesk.

Så ved hjælp af dit eksempel og James Kos svar 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 foretrækker for læsbarhed (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 f.eks. af Alexios kontrollerer bogstaveligt strengindholdet. Så at et af følgende vil resultere i falsk:

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

Den korrekte 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 

Output: This is correct!

Kommentarer

  • Der er en sandhedskerne i dit svar, men mangler nogen forklaring, det forårsager mere forvirring end det afhjælper. Det er kun lidt mere end en gentagelse af et af de tidligere svar. Hvis du ikke ønsker, at dit svar skal fjernes, skal du forklare, hvorfor det er rigtigt.

Skriv et svar

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