Mai mult
Valoare returnată într-un Bash funcție
Eu lucrez cu un script bash și vreau să execute o funcție pentru a imprima o valoare de retur:
function fun1(){
return 34
}
function fun2(){
local res=$(fun1)
echo $res
}
Cand execut fun2
, nu print "34". De ce este acest caz?
265
9
Deși bash are o "întoarcere" declarație, singurul lucru pe care puteți să specificați cu aceasta este funcția's proprii "ieșire" de stare (o valoare între 0 și
255
, 0 sensul "succes"). Atât de "returnare" nu este ceea ce vrei.Ați putea dori pentru a converti "returnare" declarația de la un "echo", declarație - că modul în funcția de ieșire ar putea fi capturat folosind
$()
bretele, care pare a fi exact ceea ce vrei.Aici este un exemplu:
Un alt mod de a obține valoarea de returnare (dacă doriți doar pentru a returna un număr întreg 0-255) e
$?
.De asemenea, rețineți că puteți folosi valoarea returnată de a utiliza logica booleană ca
fun1 || fun2
va rula doarfun2 "dacă" fun1
returnează un0
valoare. Implicit valoarea de retur este de iesire valoarea din ultima declarație de executat în funcție.$(...)
surprinde text trimis la stdout de comanda conținute în. "returnare" nu are ieșire la stdout.$?
conține codul rezultat de la ultima comanda.Funcții în Bash nu sunt funcții, cum ar fi în altă limbă; ei're de fapt comenzi. Astfel de funcții sunt folosite ca daca erau binare sau script-uri preluat de la calea ta. Din perspectiva logicii programului ar trebui să fie într-adevăr nici o diferență.
Comenzi Shell sunt conectate prin conducte (aka fluxuri), și nu fundamentale sau definite de utilizator tipuri de date, ca în "reală" limbaje de programare. Nu există nici un astfel de lucru ca o valoare de retur pentru o comanda, poate mai ales pentru că acolo's nici o cale reală de a o declara. S-ar putea să apară pe om pagină, sau
--help
ieșire de comandă, dar ambele sunt doar lizibile și, prin urmare, sunt scrise în vânt.Atunci când o comandă vrea pentru a obține de intrare se citește din fluxul de intrare, sau lista de argumente. În ambele cazuri, siruri de caractere de text trebuie să fie analizat.
Atunci când o comandă vrea să se întoarcă ceva a la "echo", la fluxul de ieșire. Un alt adesea practicat mod este de a stoca o valoare de întoarcere în dedicate, variabile globale. Scrie în fluxul de ieșire este mai clar și mai flexibil, deoarece aceasta poate duce, de asemenea, date binare. De exemplu, vă puteți întoarce o PATĂ de cerneală cu ușurință:
Ca altii au scris in acest thread, apelantul poate, de asemenea, utilizați comanda înlocuire
$()
pentru a captura de ieșire.În paralel, funcția ar fi "întoarcere" codul de ieșire din gpg
(GnuPG). Cred că de codul de ieșire ca un bonus pe care alte limbi nu't au, sau, în funcție de temperament, ca un "Schmutzeffekt" de coajă de funcții. Acest statut este, prin convenție, de la 0 la succes sau un număr întreg în intervalul 1-255 pentru altceva. Pentru a face acest lucru clar:
return` (ca "ieșire") poate lua o valoare dintr-0-255, și alte valori decât 0 nu sunt neapărat erori, cum se afirmă adesea.Când don't oferi o valoare explicită cu "revenirea" statutul este luat de la ultima comandă într-un Bash/declarație de funcție/de comandă și așa mai departe. Astfel încât există întotdeauna un statut, și "întors" este doar o modalitate ușoară de a oferi.
"Returnare" declarație stabilește codul de ieșire din funcție, la fel ca "ieșire" va face pentru întregul scenariu.
Codul de ieșire pentru ultima comandă este întotdeauna disponibil în
$?
variabil.Problema cu alte răspunsuri se vor folosi fie un globale, care pot fi suprascrise atunci când mai multe funcții sunt într-un apel lanț, sau "echo", ceea ce înseamnă că funcția nu poate ieșire informații de diagnosticare (vei uita de funcția ta face acest lucru și "rezultat", adică valoarea de returnare, va conține mai multe informații decât apelantul așteaptă, ceea ce duce la bug ciudat), sau "eval" care este mult prea greu și murdari.
Modul corect de a face acest lucru este de a pune la nivelul de sus lucrurile într-o funcție și de a folosi un "local" cu bash's dinamică de definire a domeniului statului. Exemplu:
Acest ieșiri
Dinamică de definire a domeniului înseamnă că
ret_val
puncte pentru un obiect diferit în funcție de apelant! Acest lucru este diferit de definire a domeniului lexical, care este ceea ce majoritatea limbajelor de programare utilizat. Aceasta este de fapt un documentate feature, doar ușor de dor, și nu foarte bine explicat, aici este documentația pentru ea (sublinierea este a mea):Pentru cineva cu un C/C++/Python/Java/C#/javascript fundal, aceasta este, probabil, cel mai mare obstacol: funcții în bash nu sunt funcții, acestea sunt comenzi, si se comporta ca atare: ele pot de ieșire la
stdout
/`stderr, se pot conducta in/out, se poate returna un cod de ieșire. Practic nu există nici o diferență între a defini o comandă într-un scenariu și de a crea un executabil care poate fi apelat din linia de comandă.Deci, în loc de a scrie script-ul astfel:
scrie asa:
unde
main()
declararet_val
ca "locale" și toate celelalte funcții returnează valori prinret_val
.A se vedea, de asemenea, următoarele Unix & Linux întrebare: domeniul de Aplicare al Variabilelor Locale în Coajă Functions.
Un altul, poate chiar mai bună soluție în funcție de situație, este unul postat de tine.teck, care folosește locale -n`.
Un alt mod de a realiza acest lucru este numele referințe (necesită Bash 4.3+).
Îmi place să fac următoarele cazul în care rulează într-un scenariu în cazul în care funcția este definită de:
Îmi place acest lucru, pentru că pot include apoi echo declarații în funcții dacă vreau
Ca un add-on pentru alții' excelente de posturi, aici's un articol rezumând aceste tehnici:
Revenind la Valorile de la Bash Funcții
Git Bash pe Windows folosind tablouri pentru mai multe valori de returnare
BASH COD: