Returnarea unei valori dintr-o funcție bash

Am o funcție care returnează 1 dacă numărul este un număr valid cu zece cifre:

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 } 

Este apelat de:

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

Funcția funcționează bine dacă numărul este valid, dar afișează sintaxa eroare dacă introduceți un număr nevalid.

Răspuns

Răspunsul

@choroba „este corect, totuși acest exemplu ar putea fi mai clar:

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

Acest exemplu este puțin mai lung (setarea $valNumResult apoi interogarea valorii respective), dar descrie mai explicit ce se întâmplă: acel valNum() returnează o valoare, iar acea valoare poate fi interogată și testată.

PS Vă rugăm să vă faceți o favoare și să returnați 0 pentru true și non-zero pentru false. În acest fel puteți utiliza valoarea returnată pentru a indica „de ce am eșuat” în cazul eșecului.

Răspuns

Funcțiile din bash pot returna doar coduri de ieșire. Înlocuirea comenzii, invers, este utilizată pentru a obține ieșirea standard a unui comandă sau funcție. Prin urmare, pentru a verifica semnalizatorul returnat, nu aveți nevoie de înlocuire:

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

Dar, pentru ca acesta să funcționeze, ar trebui să returnați 0 dacă numărul este valid, și 1 dacă nu este (codul de ieșire 0 nu înseamnă nicio eroare).

Comentarii

  • Nu o primesc. În exemplul 24.7 din tldp.org/LDP/abs/html/complexfunct.html funcția returnează valoarea maximă și nu codul de ieșire. Deși sugestia dvs. funcționează, dar nu sunt în măsură să înțeleg de ce funcționează
  • deoarece testul dvs. este să aflați dacă intrarea este un număr întreg de 10 cifre valid sau nu, adică adevărat sau fals, funcția returnează fie 0, fie 1. exemplul choroba ‘ funcționează deoarece if valnum "$num" este echivalent cu if valnum "$num" = 0 adică ” dacă este adevărat „. regula de bază în scriptul sh este că 0 = true / success, non-zero = false / error.
  • BTW, acel ” Advanced Bash-Scripting Guide ” nu este ‘ un ghid foarte bun – este ‘ greșit despre multe lucruri și încurajează unele practici slabe de scriptare. Întrebările frecvente despre Bash la mywiki.wooledge.org/BashFAQ este o resursă mult mai bună.
  • consultați unix.stackexchange.com/questions/12236/ …
  • funcția dvs. eșuează, deoarece repetă șirul ” Număr nevalid „, iar apoi faceți o comparație numerică între acel șir și numărul 1 cu if [[ $(valNum $num) -eq 1 ]]

Răspuns

Nu puteți returna un rezultat arbitrar dintr-o funcție shell. Puteți returna doar un cod de stare care este un număr întreg între 0 și 255. (Deși puteți transmite o valoare mai mare la return, acesta este modulul trunchiat 256.) Valoarea trebuie să fie 0 pentru a indica succesul și o valoare diferită pentru a indica eșecul; prin convenție, ar trebui să rămâneți la codurile de eroare cuprinse între 1 și 125, deoarece valorile superioare au o semnificație specială (comanda externă greșită pentru 126 și 127, ucisă de un semnal pentru valori mai mari).

Deoarece întoarceți un da-sau-nu rezultat aici, un cod de stare este potrivit. Deoarece flag pare să indice un succes sau un eșec, ar trebui să utilizați valorile convenționale de 0 pentru succes și 1 pentru eșec (opusul a ceea ce ați scris). Puteți utiliza funcția dvs. direct într-o instrucțiune 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 

Dacă trebuie să discriminați între codurile de eșec, apelați direct funcția. Imediat după revenire, codul de eroare este disponibil în $?. O puteți verifica apoi cu o declarație de caz:

valNum "$num" case $? in … 

Dacă trebuie să utilizați codul de stare mai târziu, salvați-l într-o altă variabilă înainte de $? este suprascris de următoarea comandă.

valNum "$num" valNum_status=$? 

Ceea ce ați scris nu a funcționat deoarece substituirea comenzii $(…) se extinde la ieșirea funcției, care în codul dvs. este fie mesajul de eroare, fie gol, niciodată 1.

Dacă aveți nevoie pentru a transmite mai multe informații decât permite un cod de stare din funcțiile shell, aveți două posibilități:

  • Imprimați un text pe ieșirea standard și apelați funcția într-o substituție de comandă: $(valNum "$num")
  • Atribuiți uneia sau mai multor variabile din interiorul funcției și citiți aceste variabile ulterior.

Răspundeți

Am avut rezultate contradictorii în acest domeniu. Iată rezultatele experimentelor mele empirice.În primul rând, unele „ teorii ” despre comenzile bash sau * nix:

  • SUCCES == 0 … anume. fără cod de stare de eroare)
  • FAIL              ! = 0 …… un anumit cod de stare

Exemplu:

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

Ieșire:

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

După cum se arată, comanda ls returnează codul de stare = 2. Când încercați un director valid, starea este zero ( 0 ). Nu este la fel ca aproape toate celelalte limbi.

rule # 1 – Faceți …

  • TRUE   == 0
  • FALS! = 0

Trebuie să ne amintim că testăm codurile de eroare într-un Bash if declarație. Am setat constante sau puteți utiliza comenzi shell true sau 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 

și ieșire:

Invalid Number Not lucky. 

Cu toate acestea, vă sugerez să dați orice „ up-vote „@Gilles pentru că răspunsul său este cel corect. Am vrut doar să obțin partea simplistă pe ePaper.

Un alt lucru, test comandă. Acesta arată ca:

[[ some-expression ]]; 

De cele mai multe ori. Și de exemplu:

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

Zero (0) fiind true . De ce? Ei bine, pagina de manual spune că un singur argument este „ adevărat ” atunci când este NU-NUL.

referințe:

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *