Ich arbeite mit einem Bash-Skript und möchte eine Funktion zum Drucken eines Rückgabewerts ausführen:
function fun1(){
return 34
}
function fun2(){
local res=$(fun1)
echo $res
}
Wenn ich ausführe fun2
, wird "34" nicht gedruckt. Warum ist das so?
bash
function
return-value
Mindia
quelle
quelle
return
in deinem Fall ist im Wesentlichen der gleiche wieexit code
der Bereich von0 - 255
. Verwenden Sieecho
wie von @septi vorgeschlagen. Exit-Codes können mit erfasst werden$?
.function a() { echo 34; }
function b() { while read data; do echo $data ; done ;}
a | b
Antworten:
Obwohl bash eine
return
Anweisung hat, können Sie damit nur den eigenenexit
Status der Funktion angeben (ein Wert zwischen0
und255
, 0 bedeutet "Erfolg"). Alsoreturn
ist nicht was du willst.Möglicherweise möchten Sie Ihre
return
Anweisung in eineecho
Anweisung konvertieren. Auf diese Weise kann Ihre Funktionsausgabe in$()
geschweiften Klammern erfasst werden. Dies scheint genau das zu sein, was Sie möchten.Hier ist ein Beispiel:
Eine andere Möglichkeit, den Rückgabewert abzurufen (wenn Sie nur eine Ganzzahl 0-255 zurückgeben möchten), ist
$?
.Beachten Sie außerdem, dass Sie den Rückgabewert verwenden können, um eine boolesche Logik zu verwenden,
fun1 || fun2
die nur ausgeführt wird,fun2
wennfun1
ein0
Wert zurückgegeben wird. Der Standardrückgabewert ist der Exit-Wert der letzten innerhalb der Funktion ausgeführten Anweisung.quelle
fun1
und dann wird der Rückgabewert in gespeichert$?
. Obwohl ich das nicht empfehlen würde ...$?
?||
Konstrukt ein Exit-Code von 0 als Erfolg und daher als "wahr" angesehen. Nicht Null ist ein Fehler und daher falsch.fun1 || fun2
Stellen Sie sich eine Abkürzung für "wenn fun1 Erfolg zurückgibt oder fun2 Erfolg zurückgibt" vor, anstatt einen Operator für die tatsächlichen Rückgabewerte selbst.$(...)
Erfasst den Text, der mit dem darin enthaltenen Befehl an stdout gesendet wurde.return
wird nicht an stdout ausgegeben.$?
enthält den Ergebniscode des letzten Befehls.quelle
return
wird für die Einstellung verwendet, bei der es sich um$?
die handeltexit status
. In dem obigen Beispielfun1
istexit status
wäre34
. Beachten Sie$(...)
außerdem , dass neben stdout auch stderr aus dem angegebenen Befehl erfasst wird.Funktionen in Bash sind keine Funktionen wie in einer anderen Sprache. Sie sind tatsächlich Befehle. Funktionen werden also so verwendet, als wären sie Binärdateien oder Skripte, die aus Ihrem Pfad abgerufen wurden. Aus der Sicht Ihrer Programmlogik sollte es wirklich keinen Unterschied geben.
Shell-Befehle sind durch Pipes (auch bekannt als Streams) verbunden und nicht durch grundlegende oder benutzerdefinierte Datentypen wie in "echten" Programmiersprachen. Es gibt keinen Rückgabewert für einen Befehl, vielleicht hauptsächlich, weil es keine echte Möglichkeit gibt, ihn zu deklarieren. Es kann auf der Manpage oder der
--help
Ausgabe des Befehls auftreten, aber beide sind nur für Menschen lesbar und daher in den Wind geschrieben.Wenn ein Befehl eine Eingabe erhalten möchte, liest er ihn aus seinem Eingabestream oder der Argumentliste. In beiden Fällen müssen Textzeichenfolgen analysiert werden.
Wenn ein Befehl etwas zurückgeben möchte, muss er
echo
es an seinen Ausgabestream zurückgeben. Eine andere häufig praktizierte Methode besteht darin, den Rückgabewert in dedizierten globalen Variablen zu speichern. Das Schreiben in den Ausgabestream ist klarer und flexibler, da es auch Binärdaten aufnehmen kann. Sie können beispielsweise ein BLOB einfach zurückgeben:Wie andere in diesem Thread geschrieben haben, kann der Aufrufer auch die Befehlsersetzung verwenden
$()
, um die Ausgabe zu erfassen.Parallel dazu würde die Funktion den Exit-Code von
gpg
(GnuPG) "zurückgeben" . Stellen Sie sich den Exit-Code als Bonus vor, den andere Sprachen nicht haben, oder je nach Temperament als "Schmutzeffekt" von Shell-Funktionen. Dieser Status ist gemäß Konvention 0 bei Erfolg oder eine Ganzzahl im Bereich von 1 bis 555 für etwas anderes. Um dies klar zu machen:return
(likeexit
) kann nur einen Wert von 0-255 annehmen, und andere Werte als 0 sind nicht unbedingt Fehler, wie oft behauptet wird.Wenn Sie keinen expliziten Wert
return
angeben, wird der Status aus dem letzten Befehl in einer Bash-Anweisung / Funktion / Befehl usw. übernommen. Es gibt also immer einen Status und esreturn
ist nur eine einfache Möglichkeit, ihn bereitzustellen.quelle
Die
return
Anweisung legt den Exit-Code der Funktion fest, ähnlich wieexit
für das gesamte Skript.Der Exit-Code für den letzten Befehl ist immer in der
$?
Variablen verfügbar .quelle
Das Problem bei anderen Antworten ist, dass sie entweder eine globale Funktion verwenden, die überschrieben werden kann, wenn sich mehrere Funktionen in einer Aufrufkette befinden, oder
echo
dass Ihre Funktion keine Diagnoseinformationen ausgeben kann (Sie werden vergessen, dass Ihre Funktion dies tut und das "Ergebnis", dh zurück Wert, enthält mehr Informationen als Ihr Anrufer erwartet, was zu einem seltsamen Fehler führt) odereval
der viel zu schwer und hackig ist.Der richtige Weg, dies zu tun, besteht darin, das Material der obersten Ebene in eine Funktion
local
einzufügen und eine mit Bashs dynamische Scoping-Regel zu verwenden. Beispiel:Dies gibt aus
Dynamisches Scoping bedeutet, dass
ret_val
je nach Anrufer auf ein anderes Objekt verweist! Dies unterscheidet sich vom lexikalischen Scoping, das in den meisten Programmiersprachen verwendet wird. Dies ist eigentlich eine dokumentierte Funktion , die leicht zu übersehen und nicht sehr gut erklärt ist. Hier ist die Dokumentation dazu (Schwerpunkt liegt bei mir):Für jemanden mit einem C / C ++ / Python / Java / C # / Javascript-Hintergrund ist dies wahrscheinlich die größte Hürde: Funktionen in Bash sind keine Funktionen, sie sind Befehle und verhalten sich als solche: Sie können an
stdout
/ ausgebenstderr
, sie können einleiten / out können sie einen Exit-Code zurückgeben. Grundsätzlich gibt es keinen Unterschied zwischen dem Definieren eines Befehls in einem Skript und dem Erstellen einer ausführbaren Datei, die über die Befehlszeile aufgerufen werden kann.Also anstatt dein Skript so zu schreiben:
schreibe es so:
Dabei
main()
deklariertret_val
aslocal
und alle anderen Funktionen geben Werte über zurückret_val
.Siehe auch die folgende Unix- und Linux-Frage: Umfang lokaler Variablen in Shell-Funktionen .
Eine andere, vielleicht sogar bessere Lösung je nach Situation, ist derjenige von ya.teck geschrieben welche Anwendungen
local -n
.quelle
Eine andere Möglichkeit, dies zu erreichen, sind Namensreferenzen (erfordert Bash 4.3+).
quelle
-n <name>=<reference>
tut: macht die neu erstellte Variable zu einem Verweis auf eine andere, auf die verwiesen wird<reference>
. Weitere Zuweisungen an<name>
werden für die referenzierte Variable durchgeführt.Ich möchte Folgendes tun, wenn ich in einem Skript ausgeführt werde, in dem die Funktion definiert ist:
Ich mag das, weil ich dann Echoanweisungen in meine Funktionen aufnehmen kann, wenn ich möchte
quelle
Als Ergänzung zu den hervorragenden Beiträgen anderer finden Sie hier einen Artikel, in dem diese Techniken zusammengefasst werden:
Rückgabe von Werten aus Bash-Funktionen
quelle
Git Bash unter Windows verwendet Arrays für mehrere Rückgabewerte
BASH CODE:
ERWARTETE AUSGABE:
quelle