Een waarde retourneren uit een bash-functie

Ik heb een functie die 1 retourneert als het getal een geldig tiencijferig getal is:

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 } 

Het wordt aangeroepen door:

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

De functie werkt prima als het nummer geldig is maar de syntaxis vertoont fout als u een ongeldig nummer invoert.

Antwoord

@choroba “s antwoord is correct, maar dit voorbeeld is misschien duidelijker:

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

Dit voorbeeld is iets langer (instelling $valNumResult en vervolgens die waarde opvragen), maar beschrijft explicieter wat er gebeurt: dat valNum() retourneert een waarde, en die waarde kan worden opgevraagd en getest.

PS Doe jezelf een plezier en retourneer 0 voor true en niet-nul voor false. Op die manier kunt u de geretourneerde waarde gebruiken om aan te geven “waarom we hebben gefaald” in het geval van een fout.

Answer

Functies in bash kunnen alleen exitcodes retourneren. De opdrachtsubstitutie wordt daarentegen gebruikt om de standaarduitvoer van een commando of functie. Daarom, om de geretourneerde vlag te controleren, heb je de vervanging niet nodig:

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

Maar om het te laten werken, zou je 0 moeten retourneren als het nummer is geldig, en 1 als dit niet het geval is (afsluitcode 0 betekent geen fout).

Reacties

  • Ik snap het niet. In het voorbeeld 24.7 in tldp.org/LDP/abs/html/complexfunct.html retourneert de functie de maximale waarde en niet de afsluitcode. Hoewel uw suggestie werkt, maar ik kan niet begrijpen waarom het werkt
  • aangezien uw test is om erachter te komen of de invoer een geldig geheel getal van 10 cijfers is of niet, dwz waar of niet waar, de functie geeft 0 of 1 terug. choroba ‘ s voorbeeld werkt omdat if valnum "$num" gelijk is aan if valnum "$num" = 0 dwz ” als het waar is “. basisregel bij sh-scripting is dat 0 = waar / succes, niet-nul = onwaar / fout.
  • Trouwens, dat ” Advanced Bash-Scripting Guide ” isn ‘ een zeer goede gids – het heeft ‘ in veel dingen verkeerd en moedigt enkele slechte scriptpraktijken aan. de Bash FAQ op mywiki.wooledge.org/BashFAQ is een veel betere bron.
  • zie unix.stackexchange.com/questions/12236/ …
  • je functie werkt niet omdat het de string ” Ongeldig nummer “, en je doet dan een numerieke vergelijking tussen die string en het nummer 1 met if [[ $(valNum $num) -eq 1 ]]

Answer

Je kunt geen willekeurig resultaat van een shell-functie teruggeven. U kunt alleen een statuscode retourneren die een geheel getal is tussen 0 en 255. (Hoewel u een grotere waarde kunt doorgeven aan return, wordt deze modulo 256 afgekapt.) De waarde moet 0 zijn om succes aan te geven en een andere waarde om mislukking aan te geven; volgens afspraak zou je je aan foutcodes tussen 1 en 125 moeten houden, aangezien hogere waarden een speciale betekenis hebben (slecht extern commando voor 126 en 127, gedood door een signaal voor hogere waarden).

Omdat je een ja-of-nee resultaat hier, een statuscode is geschikt. Aangezien flag een succes of mislukking lijkt aan te geven, moet u de conventionele waarden 0 gebruiken voor succes en 1 voor mislukking (het tegenovergestelde van wat u hebt geschreven). U kunt uw functie dan direct in een if-statement gebruiken.

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 

Als u onderscheid moet maken tussen foutcodes, roep de functie dan direct op. Direct nadat het is teruggekeerd, is de foutcode beschikbaar in $?. U kunt deze dan controleren met een case-instructie:

valNum "$num" case $? in … 

Als u de statuscode later nodig heeft, sla deze dan op in een andere variabele vóór $? wordt overschreven door het volgende commando.

valNum "$num" valNum_status=$? 

Wat je schreef werkte niet omdat het vervangen van het commando $(…) breidt uit naar de uitvoer van de functie, die in je code ofwel de foutmelding is of leeg is, nooit 1.

Als je het nodig hebt om meer informatie door te geven dan een statuscode toestaat uit een shell-functies, heb je twee mogelijkheden:

  • Druk wat tekst af op standaarduitvoer en roep de functie aan in een opdrachtsubstitutie: $(valNum "$num")
  • Wijs toe aan een of meer variabelen binnen de functie en lees die variabelen later.

Antwoord

Ik heb zelf tegenstrijdige resultaten op dit gebied. Hier zijn de resultaten van mijn empirische experimenten.Ten eerste wat “ theorie ” over bash- of * nix-commandos:

  • SUCCESS == 0 … namelijk. geen foutstatuscode)
  • FAIL              ! = 0 …… een statuscode

Voorbeeld:

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

Uitvoer:

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

Zoals weergegeven, retourneert de ls -opdracht statuscode = 2. Wanneer u een geldige directory probeert, is de status nul ( 0 ). Niet hetzelfde als bijna alle andere talen.

regel # 1 – Maak …

  • WAAR   == 0
  • FALSE! = 0

We moeten niet vergeten dat we foutcodes testen in een Bash if -instructie. Ik heb constanten ingesteld, of je kunt shell true of false commandos gebruiken.

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 

en output:

Invalid Number Not lucky. 

Ik raad je echter aan om “ up-vote “@Gilles omdat zijn antwoord de juiste is. Ik wilde gewoon de simplistische kant naar beneden halen in ePaper.

Nog één ding, de test commando. Dit ziet er als volgt uit:

[[ some-expression ]]; 

Meestal. En bijvoorbeeld:

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

Nul (0) is waar . Waarom? Nou, de man-pagina zegt dat een enkel argument “ true ” is als het NOT-NULL is.

referenties:

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *