Spune că am o funcție bash așa:
gmx(){ echo "foo"; }
această funcție implicit returnează valoarea de ieșire a comenzii echo
sau este necesară returnarea?
gmx(){ echo "foo"; return $? }
Presupun că bash funcționează, starea de ieșire a comenzii finale a funcției bash este cea care este „returnată”, dar nu 100% sigură.
Răspuns
return
revine explicit dintr-o funcție shell sau„ dot script ”(un script sursat). Dacă return
nu este executat, se face o returnare implicită la sfârșitul funcției shell sau a scriptului punct.
Dacă return
este executat fără parametru, este echivalent cu returnarea stării de ieșire a celei mai recente comenzi executate.
Așa funcționează return
în toate POSIX cochilii.
De exemplu,
gmx () { echo "foo" return "$?" }
este, prin urmare, echivalent cu
gmx () { echo "foo" return }
care este la fel ca
gmx () { echo "foo" }
În general, este foarte rar să utilizați $?
deloc. Este într-adevăr necesar numai dacă trebuie să-l salvați pentru utilizare ulterioară, de exemplu dacă trebuie să investigați valoarea acesteia de mai multe ori (caz în care ați atribui valoarea acesteia unei variabile și efectuați o serie de teste pe acea variabilă) / p>
Comentarii
Răspuns
Din bash(1)
pagina manuală:
Când este executată, starea de ieșire a unei funcții este starea de ieșire a ultimei comenzi executate în corp.
Comentarii
- corect, și un corolar ar putea fi că declarația return nu este altceva decât starea de ieșire?
- Cred că
return
este o comandă încorporată – deșireturn 1
este diferit deexit 1
, așa că - ” return [n]: determină oprirea executării unei funcții și returnarea valorii specificate de n către apelantul său. Dacă n este omis, starea de returnare este cea a ultimei comenzi executate în corpul funcției. ” (ibid) Deci,
return
forțează starea de ieșire a unei funcții la o anumită valoare, dacă este specificat. - @AlexandwrMills Da,
return
șiexit
sunt ambele încorporate, cu excepția faptului căreturn
poate fi utilizat numai în cadrul funcției. Nu puteți ‘ t finaliza un script cureturn
. Starea de ieșire este valoarea pe care o returnează comanda.return
este o comandă care returnează acea valoare. Deci, ” declarația de returnare nu este altceva decât starea de ieșire ” pur și simplu nu este destul de precisă. Una este o valoare, cealaltă este comanda plus valoare. - @AlexanderMills,
return
revine din funcție,exit
iese din întreaga coajă. ‘ este exact la fel ca în, să spunem C cureturn
vs.exit(n)
, saureturn
vs.sys.exit()
în Python.
Răspuns
Voi adăuga doar câteva note de precauție la răspunsurile deja furnizate:
-
Chiar dacă
return
are o semnificație foarte specială pentru shell, din punct de vedere al sintaxei, este o comandă integrată a shell-ului și o instrucțiune return este analizat ca orice altă comandă simplă. Deci, asta înseamnă că, la fel ca în argumentul oricărei alte comenzi,$?
atunci când nu este citat, ar fi supus divizării + globDeci, trebuie să citați
$?
pentru a o evita:return "$?"
-
return
de obicei nu acceptă nicio opțiune (ksh93
„s acceptă--help
obișnuit,--man
,--author
… totuși) Singurul argument pe care îl așteaptă (opțional) este codul de returnare. Gama de coduri de returnare acceptate variază de la shell la shell și dacă vreo valoare în afara de 0..255 este reflectată corect în
variază, de asemenea, de la coajă la coajă. Consultați Cod de ieșire implicit când procesul este încheiat? pentru detalii despre acest lucru.
Majoritatea shell-urilor acceptă numere negative (la urma urmei, argumentul a fost apelul de sistem _exit()
/ exitgroup()
este un int
, deci cu valori care să cuprindă cel puțin – 2 31 la 2 31 -1, deci are sens doar că shell-urile acceptă același interval pentru funcțiile sale).
Majoritatea shell-urilor utilizează waitpid()
și co. API pentru a prelua starea de ieșire, cu toate acestea, caz în care, este „trunchiat la un număr între 0 și 255 când stocat în $?
. Chiar dacă invocă o funcție nu implică apariția unui proces și folosit waitpid()
pentru a-și recupera starea de ieșire, deoarece totul se face în același proces, multe cochilii imită, de asemenea, că waitpid()
comportament atunci când invocați funcții. Ceea ce înseamnă că, chiar dacă apelați return
cu o valoare negativă, $?
va conține un număr pozitiv.
Acum, printre acele shell-uri al căror return
acceptă numere negative (ksh88, ksh93, bash, zsh, pdksh și alte derivate decât mksh, yash), există câteva ( pdksh și yash) care au nevoie de el scris ca return -- -123
altfel că -123
este luat ca trei -1
, -2
, -3
opțiuni nevalide.
Ca pdksh și de rivative (cum ar fi OpenBSD sh
sau posh
) păstrează numărul negativ din $?
, ceea ce înseamnă că a face return "$?"
ar eșua atunci când $?
conține un număr negativ (ceea ce s-ar întâmpla când ultima comandă de rulare a fost o funcție care a returnat un număr negativ ).
Deci, return -- "$?"
ar fi mai bun în acele cochilii. Cu toate acestea, rețineți că, deși este susținut de majoritatea shell-urilor, această sintaxă nu este POSIX și, în practică, nu este susținută de mksh
și de derivați de cenușă.
Deci, pentru a rezuma, cu shell-uri bazate pe pdksh, puteți utiliza numere negative în argumentele funcțiilor, dar dacă da, return "$@"
nu va funcționa. În alte shell-uri, return "$@"
va funcționa și ar trebui să evitați utilizarea numerelor negative (sau numere în afara de 0..255) ca argumente pentru return
.
În toate shell-urile pe care le știu, apelarea return
din interiorul unui subshell care rulează în interiorul unei funcții va provoca ieșirea subshell-ului (cu starea de ieșire furnizată dacă există sau cea a ultimei comenzi run), dar altfel nu va provoca o revenire de la funcție (pentru mine, nu este clar dacă POSIX vă oferă acea garanție, unii susțin că exit
ar trebui să fie folosit în loc de exit subshells funcții interne). De exemplu,
f() { (return 3) echo "still inside f. Exit status: $?" } f echo "f exit status: $?"
va genera:
still inside f. Exit status: 3 f exit status: 0
Răspuns
Da, valoarea de returnare implicită a unei funcții este starea de ieșire a ultimului executat Comanda . Acest lucru este valabil și în orice moment al oricărui script shell. În orice moment al secvenței de execuție a scriptului, starea actuală de ieșire este starea de ieșire a ultimei comenzi executate. Chiar și comanda executată ca parte a unei atribuiri variabile: var=$(exit 34)
. Diferența cu funcțiile este că o funcție ar putea modifica starea de ieșire la sfârșitul executării funcției.
Modalitatea alternativă de a schimba „starea de ieșire actuală” este de a porni un sub shell și de a-l ieși cu orice stare de ieșire necesară:
$ $(exit 34) $ echo "$?" 34
Și da, starea de ieșire expansiune trebuie să fie citat:
$ IFS="123" $ $(exit 34) $ echo $? 4
Un (exit 34)
funcționează și el.
Unii ar putea susține că o construcție mai robustă ar trebui să fie $(return 34)
și că o ieșire ar trebui să „părăsească” scriptul care se execută. Dar $(return 34)
nu funcționează cu nicio versiune a bash. Deci, nu este portabil.
Cel mai sigur mod de a seta o stare de ieșire este să-l utilizați așa cum a fost conceput pentru a funcționa, defini și return
dintr-o funcție :
exitstatus(){ return "${1:-"$?"}"; }
Deci, la sfârșitul unei funcții. este exact echivalent să nu ai nimic sau return
sau return "$?"
. Sfârșitul unei funcții nu trebuie să însemne „ultima linie de cod a unei funcții”.
#!/bin/sh exitstatus(){ a="${1:-"$?"}"; return "$a"; } gmx(){ if [ "$1" = "one" ]; then printf "foo "; exitstatus 78 return "$?" elif [ "$1" = "two" ]; then printf "baz "; exitstatus 89 return else printf "baz "; exitstatus 90 fi }
Se va imprima:
$ ./script foo 78 baz 89 baz 90
Singura utilizare practică pentru "$?"
este fie să tipăriți valoarea: echo "$?"
, fie să stocați o într-o variabilă (deoarece este o valoare efemeră și se schimbă cu fiecare comandă executată): exitstatus=$?
(nu uitați să citiți variabila în comenzi precum export EXITSTATUS="$?"
.
În comanda return
, intervalul valid de valori este în general de la 0 la 255, dar înțelegeți că valorile 126 + n
sunt utilizate de unele shell-uri pentru a semnaliza starea de ieșire specială, așadar, recomandarea generală este să folosiți 0-125.
return
este acela pentru funcțiile definite caf() (...; cmd; return)
, împiedică optimizarea pe care o fac câteva shell-uri pentru a rulacmd
în același proces ca subshell-ul. Cu multe shell-uri, asta înseamnă, de asemenea, că starea de ieșire a funcției nu ‘ nu poartă informația căcmd
a fost ucis când a fost (majoritatea shell-urilor nu pot ‘ oricum să preia aceste informații).sh
sauposh
), aveți nevoie ‘ dereturn -- "$?"
dacă a existat un șansa ca ultima comandă să fie o funcție care a returnat un număr negativ.mksh
(bazat și pe pdksh) interzice funcțiilor să returneze valori negative.return x
decâtexit x
… singurul lucru pe care îl știu este căreturn x
nu va ieși din procesul curent.return
este folosit pentru a reveni dintr-o funcție sau un script punct.exit
face ceva complet diferit (încheie un proces).