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
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:
if valnum "$num"
motsvararif valnum "$num" = 0
dvs. " om det är sant ". grundläggande tumregel i sh-skript är att 0 = true / success, non-zero = false / error.if [[ $(valNum $num) -eq 1 ]]