Vrácení hodnoty z funkce bash

Mám funkci, která vrací 1, pokud je číslo platné desetimístné číslo:

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 } 

Začíná to volat:

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

Funkce funguje dobře, pokud je číslo platné, ale zobrazuje syntaxi chyba, pokud zadáte neplatné číslo.

Odpověď

Odpověď @choroba je správná, ale tento příklad může být jasnější:

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

Tento příklad je o něco delší (nastavení $valNumResult poté dotazování na tuto hodnotu), ale konkrétněji popisuje, co se stane: valNum() vrací hodnotu a tuto hodnotu lze vyhledávat a testovat.

PS Udělejte si laskavost a vraťte 0 pro true a nenulové pro false. Takto můžete pomocí návratové hodnoty v případě selhání uvést „proč jsme selhali“.

Odpověď

Funkce v bash mohou vrátit pouze kódy ukončení. Substituce příkazu se naopak používá k získání standardního výstupu příkaz nebo funkce. Proto pro kontrolu vráceného příznaku nepotřebujete substituci:

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

Aby to ale fungovalo, měli byste vrátit 0, pokud číslo je platné, a 1, pokud není (kód ukončení 0 znamená žádnou chybu).

Komentáře

  • Nechápu to. V příkladu 24.7 v tldp.org/LDP/abs/html/complexfunct.html funkce vrací maximální hodnotu, nikoli návratový kód. Ačkoli váš návrh funguje, ale nejsem schopen pochopit, proč funguje
  • , protože vaším testem je zjistit, zda je vstup platné 10místné celé číslo nebo ne, tj. True nebo false, funkce vrátí buď 0, nebo 1. choroba ' s příklad funguje, protože if valnum "$num" je ekvivalentní if valnum "$num" = 0 tj. " pokud je to pravda ". základním pravidlem sh skriptování je, že 0 = true / success, non-zero = false / error.
  • BTW, že " Průvodce pro pokročilé skriptování Bash " není ' ta velmi dobrý průvodce – ' se v mnoha věcech mýlí a podporuje některé špatné skriptovací postupy. Časté dotazy k Bash na mywiki.wooledge.org/BashFAQ jsou mnohem lepším zdrojem.
  • viz unix.stackexchange.com/questions/12236/ …
  • vaše funkce selhává, protože opakuje řetězec " Neplatné číslo " a poté provedete numerické srovnání mezi tímto řetězcem a číslem 1 pomocí if [[ $(valNum $num) -eq 1 ]]

Odpověď

Z funkce shellu nemůžete vrátit libovolný výsledek. Můžete vrátit pouze stavový kód, který je celé číslo mezi 0 a 255. (I když můžete předat větší hodnotu return, je to zkrácené modulo 256.) Hodnota musí být 0 označit úspěch a jinou hodnotu označit neúspěch; podle konvence byste se měli držet chybových kódů mezi 1 a 125, protože vyšší hodnoty mají zvláštní význam (špatný externí příkaz pro 126 a 127, zabitý signálem pro vyšší hodnoty).

Protože vracíte výsledek ano-ne, je vhodný stavový kód. Protože flag naznačuje úspěch nebo neúspěch, měli byste použít konvenční hodnoty 0 pro úspěch a 1 pro neúspěch (opak toho, co jste napsali). Poté můžete svoji funkci použít přímo v příkazu if.

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 

Pokud potřebujete rozlišovat mezi poruchovými kódy, zavolejte funkci přímo. Okamžitě po jeho návratu je kód chyby k dispozici v $?. Poté jej můžete zkontrolovat pomocí příkazu case:

valNum "$num" case $? in … 

Pokud budete později potřebovat použít stavový kód, uložte jej do jiné proměnné před $? je přepsán dalším příkazem.

valNum "$num" valNum_status=$? 

To, co jste napsali, nefunguje, protože nahrazení příkazu $(…) se rozšíří na výstup funkce, která je ve vašem kódu buď chybová, nebo prázdná, nikdy 1.

Pokud potřebujete předat více informací, než umožňuje stavový kód z funkcí prostředí, máte dvě možnosti:

  • Vytisknout nějaký text na standardní výstup a zavolat funkci v substituci příkazu: $(valNum "$num")
  • Přiřadit jedné nebo více proměnným uvnitř funkce a tyto proměnné si přečíst později.

Odpovědět

Sám jsem měl v této oblasti konfliktní výsledky. Zde jsou výsledky mých empirických experimentů.Nejprve nějaká „ teorie “ o příkazech bash nebo * nix:

  • SUCCESS == 0 … viz. žádný chybový stavový kód)
  • FAIL              ! = 0 …… nějaký stavový kód

Příklad:

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

Výstup:

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

Jak je ukázáno, příkaz ls vrací status code = 2. Při pokusu o platný adresář je stav nulový ( 0 ). Ne stejné jako téměř ve všech ostatních jazycích.

pravidlo # 1 – Vytvořit …

  • TRUE   == 0
  • FALSE! = 0

Musíme si uvědomit, že testujeme chybové kódy v Bash if prohlášení. Nastavím konstanty, nebo můžete použít příkazy shell true nebo 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 

a výstup:

Invalid Number Not lucky. 

Navrhuji však dát jakýkoli „ up-vote „@Gilles, protože jeho odpověď je správná. Chtěl jsem jen dostat zjednodušující stránku dolů na ePaper.

Ještě jedna věc, test příkaz. Vypadá to takto:

[[ some-expression ]]; 

Většinu času. A například:

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

Nula (0) je true . Proč? Stránka man říká, že jediný argument je „ true “, pokud není NULL.

odkazy:

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *