Returnerar ett värde från en bash-funktion

Jag har en funktion som returnerar 1 om siffran är ett giltigt tiosiffrigt 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 uppringt av:

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

Funktionen fungerar bra om numret är giltigt men visar syntax fel om du anger ett ogiltigt nummer.

Svar

@chorobas svar är korrekt, men detta exempel kan vara tydligare:

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

Detta exempel är lite längre (att ställa in $valNumResult och sedan fråga det värdet), men beskriver mer exakt vad som händer: att valNum() returnerar ett värde och det värdet kan ifrågasättas och testas.

PS Gör dig själv en tjänst och returnera 0 för true och icke-noll för false. På så sätt kan du använda returvärdet för att ange ”varför vi misslyckades” i felfallet.

Svar

Funktioner i bash kan endast returnera utgångskoder. Kommandosubstitutionen används omvänt för att få standardutmatningen av en för att kontrollera den returnerade flaggan behöver du inte byta ut:

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

Men för att det ska fungera bör du returnera 0 om numret är giltigt, och 1 om det inte är det (utgångskod 0 betyder inget fel).

Kommentarer

  • Jag förstår inte det. I exemplet 24.7 i tldp.org/LDP/abs/html/complexfunct.html returnerar funktionen maxvärdet och inte utgångskoden. Även om ditt förslag fungerar men jag kan inte förstå varför det fungerar
  • eftersom ditt test är att ta reda på om ingången är ett giltigt 10-siffrigt heltal eller inte, dvs. sant eller falskt, funktionen returnerar antingen 0 eller 1. choroba ' s exempel fungerar eftersom if valnum "$num" motsvarar if valnum "$num" = 0 dvs. " om det är sant ". grundläggande tumregel i sh-skript är att 0 = true / success, non-zero = false / error.
  • BTW, att " Advanced Bash-Scripting Guide " isn ' en mycket bra guide – det ' är fel om många saker och uppmuntrar några dåliga manusrutiner. Vanliga frågor om Bash på mywiki.wooledge.org/BashFAQ är mycket bättre resurs.
  • se unix.stackexchange.com/questions/12236/ …
  • din funktion misslyckas eftersom den ekar strängen " Ogiltigt nummer ", och sedan gör du en numerisk jämförelse mellan den strängen och siffran 1 med if [[ $(valNum $num) -eq 1 ]]

Svar

Du kan inte returnera ett godtyckligt resultat från en skalfunktion. Du kan bara returnera en statuskod som är ett heltal mellan 0 och 255. (Medan du kan skicka ett större värde till return är det trunkerat modulo 256.) Värdet måste vara 0 att indikera framgång och ett annat värde för att indikera misslyckande; enligt konvention bör du hålla dig till felkoder mellan 1 och 125, eftersom högre värden har en speciell betydelse (dåligt externt kommando för 126 och 127, dödad av en signal för högre värden).

Eftersom du returnerar en ja eller nej resultat här, en statuskod är lämplig. Eftersom flag verkar indikera framgång eller misslyckande bör du använda de konventionella värdena 0 för framgång och 1 för misslyckande (motsatsen till vad du skrev). Du kan sedan använda din funktion direkt i ett if-uttalande.

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 

Om du behöver skilja mellan felkoder, ring funktionen direkt. Omedelbart efter att den återvänt är felkoden tillgänglig i $?. Du kan sedan kontrollera det med ett fall:

valNum "$num" case $? in … 

Om du behöver använda statuskoden senare, spara den i en annan variabel innan $? skrivs över av nästa kommando.

valNum "$num" valNum_status=$? 

Det du skrev fungerade inte eftersom kommandosubstitutionen $(…) expanderar till funktionens utgång, som i din kod är antingen felmeddelandet eller tom, aldrig 1.

Om du behöver för att skicka mer information än en statuskod tillåter från en skalfunktion, har du två möjligheter:

  • Skriv ut lite text på standardutmatning och anropa funktionen i kommandosubstitution: $(valNum "$num")
  • Tilldela en eller flera variabler i funktionen och läs dessa variabler senare.

Svar

Jag har själv haft motstridiga resultat på detta område. Här är resultat från mina empiriska experiment.För det första några ” teorier ” om bash- eller * nix-kommandon:

  • SUCCESS == 0 … dvs. ingen felstatuskod)
  • FAIL              ! = 0 …… någon statuskod

Exempel:

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

Utgång:

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

Som visat returnerar kommandot ls statuskod = 2. När du försöker en giltig katalog är status noll ( 0 ). Inte samma som nästan alla andra språk.

regel # 1 – Gör …

  • TRUE   == 0
  • FALSE! = 0

Vi måste komma ihåg att vi testar felkoder i en Bash if uttalande. Jag ställer in konstanter, eller så kan du använda kommandona 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 

och utdata:

Invalid Number Not lucky. 

Jag föreslår dock att du ger någon ” up-vote ”@ Gilles eftersom hans svar är det rätta. Jag ville bara få ner den förenklade sidan på ePaper.

Bara en annan sak, test -kommando. Det här ser ut som:

[[ some-expression ]]; 

För det mesta. Och till exempel:

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

Noll (0) är true . Varför? Man-sidan säger att ett enda argument är ” true ” när det INTE är NULL.

referenser:

Lämna ett svar

Din e-postadress kommer inte publiceras. Obligatoriska fält är märkta *