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
@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
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:
if valnum "$num"
este echivalent cuif valnum "$num" = 0
adică ” dacă este adevărat „. regula de bază în scriptul sh este că 0 = true / success, non-zero = false / error.if [[ $(valNum $num) -eq 1 ]]