Funktionsdeklarationen in einem Bash- oder Shell-Skript weiterleiten?

95

Gibt es so etwas in bashoder zumindest etwas Ähnliches (Workaround) wie Forward-Deklarationen, die zum Beispiel in C / C ++ bekannt sind?

Oder gibt es so etwas, weil es zum Beispiel immer in einem Durchgang (Zeile für Zeile) ausgeführt wird?

Was muss ich tun, um die Lesbarkeit meines Skripts zu verbessern, wenn keine Vorwärtsdeklarationen vorliegen? Es ist ziemlich lang und diese Funktionsdefinitionen am Anfang, gemischt mit globalen Variablen, lassen mein Skript hässlich und schwer zu lesen / verstehen aussehen. Ich bitte Sie, einige bekannte / bewährte Methoden für solche Fälle zu lernen.


Beispielsweise:

# something like forward declaration
function func

# execution of the function
func

# definition of func
function func
{
    echo 123
}
Kiril Kirov
quelle

Antworten:

190

Gute Frage. Ich verwende für die meisten meiner Skripte ein solches Muster:

#!/bin/bash

main() {
    foo
    bar
    baz
}

foo() {
}

bar() {
}

baz() {
}

main "$@"

Sie können den Code von oben nach unten lesen, er wird jedoch erst in der letzten Zeile ausgeführt. Durch die Übergabe "$@"an main () können Sie die Befehlszeilenargumente zuzugreifen $1, $2et al wie gewohnt.

John Kugelman
quelle
3
Hallo, wie strukturieren Sie Daten, die in Ihrem Beispiel zwischen foo / bar / baz geteilt werden müssen? Normalerweise setze ich es einfach oben in das Skript. Ist dies bei der Verwendung von Funktionen immer noch der Fall? Oder ist es besser, globale Daten in main zu setzen und sie dann als Argumente an foo / bar / baz zu übergeben? Was ist die beste Vorgehensweise?
Bodacydo
4
Ich bevorzuge Argumente. Ansonsten setze ich globale Variablen in mainoder in einer Funktion direkt danach main(z . B. setupoder parseArguments). Ich vermeide es, globale Variablen oben zu setzen main- Code sollte nicht außerhalb von liegen main.
John Kugelman
Dies scheint etwas analog zu dem, was if _ _ name _ _ == "_ _ main _ _": main()in Python tut
Sergiy Kolodyazhnyy
Dies ist auch fantastisch, wenn Sie Tools wie Bats zum Testen Ihrer Skripte verwenden. Wenn Sie alles in Funktionen aufteilen, wird das Testen der einzelnen Komponenten viel einfacher. Siehe auch Blog-Beitrag
dragon788
30

Wenn meine Bash-Skripte zu stark wachsen, verwende ich einen Include-Mechanismus:

Datei allMyFunctions:

foo() {
}

bar() {
}

baz() {
}

Datei main:

#!/bin/bash

. allMyfunctions

foo
bar
baz
Mouviciel
quelle
27
Persönlich, wenn ein Shell-Skript über eine Datei hinaus wächst, neige ich dazu, in eine andere Sprache zu wechseln ;-)
Joachim Sauer
Wäre es nicht besser zu benutzen source allMyfunctions?
Pydoge
4
@pydoge: sourceist nicht POSIX-konform. bashdefiniert sourceals Alias ​​für .: Sie sind funktional äquivalent.
Mouviciel