Was ist der Unterschied zwischen der return
und exit
-Anweisung in Bash-Funktionen in Bezug auf Exit-Codes?
Was ist der Unterschied zwischen der return
und exit
-Anweisung in Bash-Funktionen in Bezug auf Exit-Codes?
Antworten:
Von man bash
an return [n]
;
Bewirkt, dass eine Funktion die Ausführung beendet und den von n angegebenen Wert an ihren Aufrufer zurückgibt. Wenn n weggelassen wird, ist der Rückgabestatus der des letzten im Funktionskörper ausgeführten Befehls.
... am exit [n]
:
Bewirkt, dass die Shell mit dem Status n beendet wird. Wenn n weggelassen wird, ist der Exit-Status der des zuletzt ausgeführten Befehls. Ein Trap bei EXIT wird ausgeführt, bevor die Shell beendet wird.
BEARBEITEN:
Laut Ihrer Bearbeitung der Frage in Bezug auf Exit-Codes return
hat dies nichts mit Exit-Codes zu tun. Exit-Codes sind für Anwendungen / Skripte vorgesehen , nicht für Funktionen. In dieser Hinsicht ist das einzige Schlüsselwort, das den Exit-Code des Skripts festlegt (das vom aufrufenden Programm mithilfe der $?
Shell-Variablen abgefangen werden kann) exit
.
EDIT 2:
Meine letzte Aussage, die sich bezieht, exit
verursacht einige Kommentare. Es wurde erstellt, um das OP zu differenzieren return
und exit
zu verstehen, und tatsächlich ist es an jedem Punkt eines Programm- / Shell-Skripts exit
die einzige Möglichkeit, das Skript mit einem Exit-Code für den aufrufenden Prozess zu beenden.
Jedes in dem Shell ausgeführten Befehl erzeugt einen lokalen „Exit - Code“: es ist die Sätze $?
variabel auf diesen Code und kann mit verwendet werden if
, &&
und andere Betreiber bedingt andere Befehle auszuführen.
Diese Exit-Codes (und der Wert der $?
Variablen) werden bei jeder Befehlsausführung zurückgesetzt.
Im Übrigen wird der Exit-Code des letzten vom Skript ausgeführten Befehls als Exit-Code des Skripts selbst verwendet, wie vom aufrufenden Prozess gesehen.
Schließlich fungieren Funktionen beim Aufruf als Shell-Befehle in Bezug auf Exit-Codes. Der Exit-Code der Funktion ( innerhalb der Funktion) wird mithilfe von festgelegt return
. Wenn also eine Funktion ausgeführt return 0
wird, wird die Funktionsausführung beendet und der Exit-Code 0 angegeben.
func(){ return 50; };func;echo $?
50 wieder. Die $?
Shell-Variable scheint also nicht auf beschränkt zu sein exit
.
$?
Wird auf den Exit-Status der zuletzt ausgeführten Vordergrund-Pipeline erweitert." Dieser Exit kann aus der Shell in Form eines Aufrufs exit
(oder am Ende des Skripts) oder in Form eines Aufrufs return
innerhalb einer Funktion erfolgen.
$?
aktuelle Prozess / das aktuelle Skript ist entweder auf exit
oder auf das Ergebnis des letzten von diesem Skript ausgeführten Befehls beschränkt. Wenn Ihre letzte Skriptzeile der Aufruf dieser Funktion ist und diese Funktion 50 zurückgibt, ist die $?
, die Sie für den Prozess erzeugen , der Sie aufgerufen hat, 50. Dies hat jedoch nichts mit dem zu tun return
, da dies der Fall ist beschränkt auf das aktuelle Skript. Es wird nur zurückgegeben, wenn dieser Funktionsaufruf der letzte Satz des Skripts ist. exit
Beenden Sie jedoch immer das Skript und geben Sie diesen Wert $?
für den aufrufenden Prozess zurück .
return
hat nichts mit Exit-Codes zu tun." Experimente zeigen mir, dass es keinen funktionalen Unterschied zwischen dem Rückkehrcode einer Funktion und dem Exit-Code eines Skripts gibt.
return
bewirkt, dass die aktuelle Funktion den Gültigkeitsbereich verlässt, während exit
das Skript an der Stelle endet, an der es aufgerufen wird. Hier ist ein Beispielprogramm, um dies zu erklären:
#!/bin/bash
retfunc()
{
echo "this is retfunc()"
return 1
}
exitfunc()
{
echo "this is exitfunc()"
exit 1
}
retfunc
echo "We are still here"
exitfunc
echo "We will never see this"
$ ./test.sh
this is retfunc()
We are still here
this is exitfunc()
$?
.
echo fnord | while read x; do exitfunc; done; echo "still here"
druckt „immer noch hier“. Es scheint, dass while
in diesem Szenario nur die Sub-Shell beendet wird.
done || exit $?
aber das ist hässlich und nicht genau gleichwertig.
return
bewirkt, dass die aktuelle Funktion oder das Sourcing-Skript den Gültigkeitsbereich verlässt```.
Ich glaube nicht, dass jemand die Frage wirklich vollständig beantwortet hat, weil er nicht beschreibt, wie die beiden verwendet werden. OK Ich denke, wir wissen, dass exit das Skript beendet, wo immer es aufgerufen wird, und Sie können ihm auch einen Status zuweisen, z. B. exit oder exit 0 oder exit 7 und so weiter. Dies kann verwendet werden, um zu bestimmen, wie das Skript angehalten werden musste, wenn es von einem anderen Skript aufgerufen wurde usw. Genug beim Beenden.
return beim Aufruf gibt den angegebenen Wert zurück, der das Verhalten der Funktion angibt, normalerweise eine 1 oder eine 0. Beispiel:
#!/bin/bash
isdirectory() {
if [ -d "$1" ]
then
return 0
else
return 1
fi
echo "you will not see anything after the return like this text"
}
Überprüfen Sie wie folgt:
if isdirectory $1; then echo "is directory"; else echo "not a directory"; fi
oder so:
isdirectory || echo "not a directory"
In diesem Beispiel kann der Test verwendet werden, um anzuzeigen, ob das Verzeichnis gefunden wurde. Beachten Sie, dass nach der Rückgabe nichts in der Funktion ausgeführt wird. 0 ist wahr, aber falsch ist 1 in der Shell, anders als bei anderen Prog langs.
Weitere Informationen zu Funktionen: http://www.linuxjournal.com/content/return-values-bash-functions
HINWEIS: Die isdirectory-Funktion dient nur zu Unterrichtszwecken. Dies sollte nicht die Art und Weise sein, wie Sie eine solche Option in einem echten Skript ausführen.
test -d $1
, um das gleiche Ergebnis zu erzielen. Mach das niemals if <check> return else return
. <check>
allein wird das gleiche in allen Sprachen tun, die ich zumindest kenne.
isdirectory() { [ -d "$1" ]; }
verhält sich genauso wie hier: Der Standardrückgabewert einer Shell-Funktion, sei es durch Erreichen des Codeendes oder durch a return
ohne Argumente, ist der von letzter Befehl.
return
Aussage spricht . Es ist wahr, dass sein Beispiel simpel ist und nicht in der Produktion verwendet werden darf. Aber es ist einfach, also erfüllt es seine Aufgabe ganz gut. Daran ist nichts auszusetzen.
Denken Sie daran, dass Funktionen skriptintern sind und normalerweise mithilfe der return-Anweisung zurückgegeben werden, von wo aus sie aufgerufen wurden. Das Aufrufen eines externen Skripts ist eine ganz andere Sache, und Skripte werden normalerweise mit einer exit-Anweisung beendet.
Der Unterschied "zwischen der return- und exit-Anweisung in BASH-Funktionen in Bezug auf Exit-Codes" ist sehr gering. Beide geben einen Status zurück, keine Werte an sich. Ein Status von Null zeigt Erfolg an, während jeder andere Status (1 bis 255) einen Fehler anzeigt. Die return-Anweisung kehrt zu dem Skript zurück, von dem aus sie aufgerufen wurde, während die exit-Anweisung das gesamte Skript von der Stelle aus beendet, an der sie angetroffen wird.
return 0 # returns to where the function was called. $? contains 0 (success).
return 1 # returns to where the function was called. $? contains 1 (failure).
exit 0 # exits the script completely. $? contains 0 (success).
exit 1 # exits the script completely. $? contains 1 (failure).
Wenn Ihre Funktion einfach ohne return-Anweisung endet, wird der Status des zuletzt ausgeführten Befehls als Statuscode zurückgegeben (und in eingefügt $?
).
Denken Sie daran, dass beim Zurück- und Beenden ein Statuscode von 0 bis 255 zurückgegeben wird, der in verfügbar ist $?
. Sie können nichts anderes in einen Statuscode einfügen (z. B. "cat" zurückgeben). es wird nicht funktionieren. Ein Skript kann jedoch mithilfe von Statuscodes 255 verschiedene Fehlergründe zurückgeben.
Sie können im aufrufenden Skript enthaltene Variablen festlegen oder die Ergebnisse in der Funktion wiedergeben und die Befehlssubstitution im aufrufenden Skript verwenden. Der Zweck von Return und Exit besteht jedoch darin, Statuscodes zu übergeben, nicht Werte oder Berechnungsergebnisse, wie man es in einer Programmiersprache wie C erwarten kann.
Manchmal führen Sie ein Skript mit .
oder aus source
.
. a.sh
Wenn Sie ein exit
in das a.sh
einfügen, wird nicht nur das Skript beendet, sondern auch Ihre Shell-Sitzung beendet.
Wenn Sie ein return
in das a.sh
einfügen, wird die Verarbeitung des Skripts einfach beendet.
return: can only 'return' from a function or sourced script
, die es für ein allgemeines Skript ungeeignet macht.
all
Situationen geeignet . Verwenden .
oder source
Ausführen des Skripts in der aktuellen Shell, anstatt eine Unter-Shell zu erzeugen. Das Skript muss wissen, wie es verwendet werden soll. Wehe dem Benutzer, der es gegenüber tut. Persönlich empfehle ich, Skripte zu lesen, bevor Sie sie zum ersten Mal ausführen.
trap
Funktion für zu verwenden ERR EXIT
und dann zuerst den Exit-Code eines fehlgeschlagenen Befehls zu speichern errCode=$?
und dann das Skript (bezogen oder nicht) mit return $errCode || exit $errCode
den ||
Mitteln zu beenden : "Wenn ich nicht zurückkehren kann, weil ich nicht beschafft wurde." , stattdessen einfach beenden ".
In einfachen Worten (hauptsächlich für Anfänger in der Codierung) können wir sagen:
`return` : exits the function,
`exit()` : exits the program(called as process while running)
Auch wenn Sie beobachtet haben, ist dies sehr einfach, aber ...,
`return` : is the keyword
`exit()` : is the function
exit
ist nicht mehr oder weniger eine Funktion als return
. Sie sind integrierte Befehle. Sie sind nicht einmal reservierte Wörter.
exit
Beenden Sie den aktuellen Prozess . Betrachten Sie dies mit oder ohne Exit-Code eher als ein System als als eine Programmfunktion. Beachten Sie, dass beim Sourcing exit
die Shell beendet wird, beim Ausführen jedoch nur exit
das Skript.
return
Von einer Funktion kehren Sie nach dem Aufruf mit oder ohne Rückkehrcode zur Anweisung zurück. return
ist optional und am Ende der Funktion implizit. return
kann nur innerhalb einer Funktion verwendet werden.
Ich möchte hinzufügen, dass es während der Beschaffung nicht einfach ist, exit
das Skript innerhalb einer Funktion zu erstellen, ohne die Shell zu beenden. Ich denke, ein Beispiel ist besser für ein 'Test'-Skript
#!/bin/bash
function die(){
echo ${1:=Something terrible wrong happen}
#... clean your trash
exit 1
}
[ -f /whatever/ ] || die "whatever is not available"
# now we can proceed
echo "continue"
Gehen Sie wie folgt vor:
user$ ./test
Whatever is not available
user$
test
-und- die Shell wird geschlossen.
user$ . ./test
Whatever is not available
Nur test
wird beendet und die Eingabeaufforderung wird angezeigt.
Die Lösung besteht darin, das potenzielle Verfahren in (
und einzuschließen)
#!/bin/bash
function die(){
echo $(1:=Something terrible wrong happen)
#... clean your trash
exit 1
}
( # added
[ -f /whatever/ ] || die "whatever is not available"
# now we can proceed
echo "continue"
) # added
Jetzt wird in beiden Fällen nur beendet test
.
(
und wird )
dieser Block in eine Unter-Shell .
eingefügt, wodurch der Befehl (Quelle) effektiv aufgehoben wird, als hätten Sie das Testskript normal ausgeführt, das sich in einer Unter-Shell befindet. Wenn das Skript nicht mit ausgeführt wird .
oder source
Sie effektiv 2 Unterschalen haben.
Die Frage des OP: Was ist der Unterschied zwischen der return- und der exit-Anweisung in BASH-Funktionen in Bezug auf Exit-Codes?
Zunächst ist eine Klarstellung erforderlich:
Wählen Sie in der obigen Aufzählungsliste aus "(x | y)" entweder immer das erste Element oder immer das zweite Element, um Anweisungen zu Funktionen & Rückgabe oder Shells & Beenden zu erhalten.
Klar ist, dass beide die spezielle Variable $ gemeinsam verwenden? Werte nach Beendigung nach oben zu übergeben.
* Nun zu den besonderen Möglichkeiten, die $? kann eingestellt werden:
Es ist erwähnenswert, dass $? kann durch Aufrufen von exit in einer Sub-Shell wie folgt einen Wert zugewiesen werden:
# (exit 259)
# echo $?
3
exit 259
hallt dies wider, 3
weil der endgültige Exit-Wert ein einzelnes Byte ist. 259 % 256 = 3
Zuallererst return
ist ein Schlüsselwort und exit
mein Freund ist eine Funktion.
Das heißt, hier ist eine einfachste Erklärung.
return
Es gibt einen Wert von einer Funktion zurück.
exit
Es verlässt die aktuelle Shell oder verlässt sie.
return
es sich um ein Schlüsselwort handelt. Return ist viel mehr als nur Exit-Codes, weshalb der Vergleich nicht fair ist.
exit
noch return
"Schlüsselwörter" oder, wie das Bash-Handbuch sie nennt, "reservierte Wörter". Keiner von beiden ist eine "Funktion" im Sinne einer Bash-Funktion. Beide sind eingebaute Befehle in Bash-Jargon. (Es gibt eine C-Standardbibliotheksfunktion namens exit()
, und die C-Programmiersprache hat ein reserviertes Wort return
, aber diese sollten nicht mit den Bash-Befehlen verwechselt werden, obwohl ihre Semantik merkwürdig ähnlich ist.)
help <command>
Ihre Shell ein, um Informationen darüber zu erhalten, was eine eingebaute Shell tun wird. In Ihrem Fallhelp return
undhelp exit