Returnerer en verdi fra en bash-funksjon

Jeg har en funksjon som returnerer 1 hvis tallet er et gyldig ti-sifret nummer:

valNum() { flag=1 if [[ $1 != [1-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] ]]; then echo "Invalid Number" flag=0 fi return $flag } 

Det blir ringt av:

if [[ $(valNum $num) -eq 1 ]]; then #do something fi 

Funksjonen fungerer bra hvis tallet er gyldig, men viser syntaksen feil hvis du angir et ugyldig nummer.

Svar

@chorobas svar er riktig, men dette eksemplet kan være tydeligere:

valNum $num valNumResult=$? # "$?" is the return value of the previous command if [[ $valNumResult -eq 1 ]] then : # do something fi 

Dette eksemplet er litt lenger (innstilling av $valNumResult for å spørre om verdien), men beskriver mer eksplisitt hva som skjer: at valNum() returnerer en verdi, og den verdien kan spørres og testes.

PS Gjør deg selv en tjeneste og returner 0 for true og ikke-null for false. På den måten kan du bruke returverdien til å indikere «hvorfor vi mislyktes» i feilsaken.

Svar

Funksjoner i bash kan bare returnere utgangskoder. Kommandosubstitusjonen brukes omvendt for å få standard utgang til en For å sjekke det returnerte flagget trenger du ikke erstatning:

if valNum "$num" ; then # ... fi 

Men for at det skal fungere, bør du returnere 0 hvis nummeret er gyldig, og 1 hvis det ikke er det (utgangskode 0 betyr ingen feil).

Kommentarer

  • Jeg får det ikke. I eksemplet 24.7 i tldp.org/LDP/abs/html/complexfunct.html returnerer funksjonen maksverdien og ikke utgangskoden. Selv om forslaget ditt fungerer, men jeg ikke kan forstå hvorfor det fungerer
  • siden testen din er å finne ut om inngangen er et gyldig 10-sifret heltall eller ikke, dvs. sant eller usant, funksjonen returnerer enten 0 eller 1. choroba ' s eksempel fungerer fordi if valnum "$num" tilsvarer if valnum "$num" = 0 dvs. " hvis det er sant ". grunnleggende tommelfingerregel i sh-skripting er at 0 = true / success, non-zero = false / error.
  • BTW, at " Advanced Bash-Scripting Guide " isn ' en veldig god guide – det ' er galt med mange ting og oppmuntrer til noen dårlige skripter. Vanlige spørsmål om Bash på mywiki.wooledge.org/BashFAQ er mye bedre ressurs.
  • se unix.stackexchange.com/questions/12236/ …
  • funksjonen din mislykkes fordi den ekko strengen " Ugyldig nummer ", og du gjør da en numerisk sammenligning mellom den strengen og tallet 1 med if [[ $(valNum $num) -eq 1 ]]

Svar

Du kan ikke returnere et vilkårlig resultat fra en skallfunksjon. Du kan bare returnere en statuskode som er et heltall mellom 0 og 255. (Mens du kan overføre en større verdi til return, er den avkortet modulo 256.) Verdien må være 0 å indikere suksess og en annen verdi for å indikere svikt; etter konvensjon bør du holde deg til feilkoder mellom 1 og 125, ettersom høyere verdier har en spesiell betydning (dårlig ekstern kommando for 126 og 127, drept av et signal for høyere verdier).

Siden du returnerer en ja-eller-nei-resultat her, en statuskode er passende. Siden flag ser ut til å indikere suksess eller fiasko, bør du bruke de konvensjonelle verdiene 0 for å lykkes og 1 for feil (det motsatte av det du skrev). Du kan deretter bruke funksjonen din direkte i en if-setning.

valNum () { local flag=0 if [[ $1 != [1-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] ]]; then echo 1>&2 "Invalid Number" flag=1 fi return $flag } if valNum "$num"; then #do something fi 

Hvis du trenger å skille mellom feilkoder, kan du ringe funksjonen direkte. Rett etter at den er tilbake, er feilkoden tilgjengelig i $?. Du kan deretter sjekke det med en saksuttalelse:

valNum "$num" case $? in … 

Hvis du trenger å bruke statuskoden senere, lagrer du den i en annen variabel før $? overskrives av neste kommando.

valNum "$num" valNum_status=$? 

Det du skrev fungerte ikke fordi kommandosubstitusjonen $(…) utvides til utgangen av funksjonen, som i koden din enten er feilmeldingen eller tom, aldri 1.

Hvis du trenger for å overføre mer informasjon enn en statuskode tillater ut av skallfunksjoner, har du to muligheter:

  • Skriv ut litt tekst på standardutdata, og ring funksjonen i en kommandosubstitusjon: $(valNum "$num")
  • Tildel til en eller flere variabler i funksjonen og les disse variablene senere.

Svar

Jeg har selv hatt motstridende resultater på dette området. Her er resultater fra mine empiriske eksperimenter.For det første noen « teori » om bash- eller * nix-kommandoer:

  • SUCCESS == 0 … nemlig ingen feilstatuskode)
  • FAIL              ! = 0 …… noen statuskoder

Eksempel:

if ls -lt /nonexistantdir then echo "found" else echo "FAIL" fi # echo ls -lt /nonexistantdir; echo "status = $?" echo "status = $?" 

Utgang:

ls: cannot access "/nonexistantdir": No such file or directory FAIL... ls: cannot access "/nonexistantdir": No such file or directory status = 2 

Som vist, returnerer ls statuskode = 2. Når du prøver en gyldig katalog, er statusen null ( 0 ). Ikke det samme som nesten alle andre språk.

regel # 1 – Lag …

  • SANT   == 0
  • FALSE! = 0

Vi må huske at vi tester feilkoder i en Bash if uttalelse. Jeg setter opp konstanter, eller du kan bruke kommandoer med shell true eller false.

TRUE=0 FALSE=1 # valid number function # valNum() { flag=$TRUE if [[ $1 != [1-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] ]]; then echo "Invalid Number" flag=$FALSE fi return $flag } # later on ... # if validNum Abc then echo "Lucky number" else echo "Not lucky." fi 

og utdata:

Invalid Number Not lucky. 

Jeg foreslår imidlertid at du gir noen « up-vote «@ Gilles fordi svaret hans er det riktige. Jeg ville bare få den forenklede siden ned på ePaper.

Bare en annen ting, test kommando. Dette ser ut som:

[[ some-expression ]]; 

Mesteparten av tiden. Og for eksempel:

$ test 1 $ echo "result = $?" result = 0 $ test 0 $ echo "result = $?" result = 0 

Zero (0) being true . Hvorfor? Vel, mannssiden sier at et enkelt argument er « sant » når det IKKE er NULL.

referanser:

Legg igjen en kommentar

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