Das Problem bei anderen Antworten ist, dass sie entweder ein globales verwenden, das überschrieben werden kann, wenn mehrere Funktionen in einer Aufrufkette sind, oder echo
, was bedeutet, dass Ihre Funktion keine Diagnoseinformationen ausgeben kann (Sie werden vergessen, dass Ihre Funktion dies tut, und das "Ergebnis", d.h. der Rückgabewert, wird mehr Informationen enthalten, als Ihr Aufrufer erwartet, was zu seltsamen Fehlern führen kann), oder eval
, was viel zu schwerfällig und heftig ist.
Der richtige Weg, dies zu tun, besteht darin, die Top-Level-Dinge in eine Funktion zu setzen und Bash's dynamische Scoping-Regel mit einem local
zu verwenden. Beispiel:
func1()
{
ret_val=hi
}
func2()
{
ret_val=bye
}
func3()
{
local ret_val=nothing
echo $ret_val
func1
echo $ret_val
func2
echo $ret_val
}
func3
Dies gibt aus
nothing
hi
bye
Dynamisches Scoping bedeutet, dass ret_val
auf ein anderes Objekt zeigt, abhängig vom Aufrufer! Dies unterscheidet sich vom lexikalischen Scoping, das von den meisten Programmiersprachen verwendet wird. Dies ist tatsächlich eine dokumentierte Funktion, die leicht zu übersehen ist und nicht sehr gut erklärt wird. Hier ist die Dokumentation dazu (die Betonung liegt bei mir):
Variablen, die nur in der Funktion und den von ihr aufgerufenen Befehlen sichtbar sind, können mit dem lokalen Befehl deklariert werden.
Für jemanden mit einem C, C++, Python, Java, C# oder JavaScript-Hintergrund ist dies wahrscheinlich das größte Hindernis: Funktionen in bash sind nicht wirklich Funktionen, sondern Befehle und verhalten sich als solche: sie können auf stdout
/stderr
ausgeben, sie können ein- und ausleiten und sie können einen Exit-Code zurückgeben. Grundsätzlich gibt es keinen Unterschied zwischen der Definition eines Befehls in einem Skript und der Erstellung eines ausführbaren Programms, das von der Befehlszeile aufgerufen werden kann.
Also anstatt Ihr Skript so zu schreiben:
Spitzencodierung
Haufen von Funktionen
Mehr Spitzencodierung
schreiben Sie es so:
# Definieren Sie Ihre Hauptfunktion, die alle Spitzencodierung enthält
main()
Haufen von Funktionen
# Hauptfunktion aufrufen
main
wobei main()
ret_val
als local
deklariert und alle anderen Funktionen Werte über ret_val
zurückgeben.
Siehe auch die Frage auf Unix & Linux Bereich lokaler Variablen in Shell-Funktionen.
Ein weiterer, vielleicht sogar besserer Lösungsvorschlag, je nach Situation, ist derjenige, der von ya.teck veröffentlicht wurde und local -n
verwendet.