Im Moment entwickle ich ein größeres Bash-Skript (es ist ein Open Source-Projekt von mir) und es wird langsam zu einem Chaos. Ich habe die Logik in Funktionen aufgeteilt, lokale Variablen verwendet, wo ich kann, und nur eine Handvoll globaler Variablen deklariert. Trotzdem wird es ziemlich schwer zu warten.
Ich dachte darüber nach, das Skript in mehrere Skripte aufzuteilen und sie in meinem Hauptskript zu verwenden (ähnlich wie Importe in andere Sprachen).
Aber ich frage mich, ob dies ein praktikabler Ansatz ist. Erstens kann die Beschaffung mehrerer Skripte die Ausführungszeit des Skripts erheblich verlangsamen, und zweitens erschwert dies die Verteilung.
Ist das ein guter Ansatz und machen es andere (Open Source) Projekte genauso?
Antworten:
Ja, das ist eine gängige Praxis. In den Anfängen von Unix war der Shell-Code, der das System durch die Startphasen zum Mehrbenutzerbetrieb führte, beispielsweise eine einzelne Datei
/etc/rc
. Heutzutage wird der Startvorgang von vielen Shellskripten gesteuert, die nach Funktionen unterteilt sind und deren allgemeine Funktionen und Variablen von zentralen Standorten aus nach Bedarf bezogen werden. Linux-Distributionen, Macs und BSDs haben diesen Ansatz in unterschiedlichem Maße übernommen.quelle
Ist Shell zu diesem Zeitpunkt das richtige Werkzeug für den Job? Als Entwickler, der auf Probleme mit herauswachsendem Code gestoßen ist, kann ich Ihnen sagen, dass ein Umschreiben nicht in Betracht gezogen werden sollte, sondern die Aufteilung der Teile in etwas, das besser für den Maßstab geeignet ist, den Sie für Ihre Anwendung benötigen - vielleicht Python, Ruby oder sogar Perl ?
Shell ist eine Utility-Sprache - es ist eine Skriptsprache - und daher wird es schwierig sein, sie auf diese Größen zu erweitern.
quelle
Wenn es Ihnen die Wartung erleichtert, können Sie beides haben. Teilen Sie es in logische Teile auf, damit Sie es einfach warten können, und schreiben Sie dann (z. B.) ein Makefile, um es zur Verteilung wieder zusammenzusetzen die
source
Zeile oder machen Sie einfach etwas Triviales wie dieses (Sie müssen dies neu tabulieren, wennmake
Tabulatoren erforderlich sind):Sie haben dann eine "Quell" -Version (für die Bearbeitung verwendet) und eine "Binär" -Version (für die einfache Installation verwendet).
quelle
Ein Skript kann wie von Ihnen beschrieben aufgebrochen werden - fast alles kann getan werden. Ich würde sagen, dass der „gute Ansatz“ darin besteht, Ihr großes Skript zu unterteilen und herauszufinden, wo Teile davon als separater Prozess ausgeführt werden können, der über IPC-Mechanismen kommuniziert.
Darüber hinaus würde ich ein Shell-Skript als einzelne Datei packen. Wie Sie sagen, erschwert dies die Verteilung: Entweder müssen Sie wissen, wo sich die 'Bibliothek'-Skripte befinden - es gibt keinen netten Standard für Shell-Skripte - oder Sie müssen sich darauf verlassen, dass der Benutzer ihren Pfad korrekt einstellt.
Sie können ein Installationsprogramm verteilen, das dies alles für Sie erledigt, die Dateien extrahiert, an die richtige Stelle legt und den Benutzer
export PROGRAMDIR=$HOME/lib/PROGRAM
auffordert, der Datei ~ / .bashrc etwas Ähnliches hinzuzufügen. Das Hauptprogramm kann dann fehlschlagen, wenn$PROGRAMDIR
es nicht festgelegt ist oder die erwarteten Dateien nicht enthält.Ich würde mir nicht so viele Sorgen um den Aufwand beim Laden der anderen Skripte machen. Der Aufwand ist wirklich nur das Öffnen einer Datei; Die Verarbeitung des Textes ist die gleiche, insbesondere wenn es sich um Funktionsdefinitionen handelt.
quelle
Gängige Praxis oder nicht, ich halte nichts anderes als eine Reihe von Exporten für eine gute Idee. Ich finde, dass das Ausführen von Code durch Sourcing nur verwirrend ist und die Wiederverwendung einschränkt, da Umgebungs- und andere variable Einstellungen den Sourcing-Code stark vom Sourcing-Code abhängig machen.
Sie sollten Ihre Anwendung besser in kleinere, eigenständige Skripts aufteilen und diese dann als eine Reihe von Befehlen ausführen. Dies erleichtert das Debuggen, da Sie jedes in sich geschlossene Skript in einer interaktiven Shell ausführen und zwischen den einzelnen Befehlsaufrufen Dateien, Protokolle usw. untersuchen können. Ihr einzelnes, umfangreiches Anwendungsskript wird zu einem einfacheren Steuerungsskript, das nach dem Debuggen nur eine Reihe von Befehlen ausführt.
Eine Gruppe kleinerer, in sich geschlossener Skripte stößt auf das schwieriger zu installierende Problem.
quelle
Eine Alternative zum Sourcing der Skripte besteht darin, sie einfach mit Argumenten aufzurufen. Wenn Sie den größten Teil Ihrer Funktionalität bereits in Shell-Funktionen aufgeteilt haben, sind Sie wahrscheinlich fast in der Lage, dies bereits zu tun. Mit dem folgenden Codeausschnitt von Bash kann jede in einem Skript deklarierte Funktion als Unterbefehl verwendet werden:
Der Grund, dies nicht zu tun,
source
ist die Vermeidung von Umwelt- und Optionsverschmutzung.quelle
Hier ist mein Beispiel, wie ein großes Bash-Skript in mehrere Dateien aufgeteilt und dann in ein daraus resultierendes Skript integriert werden kann: https://github.com/zinovyev/bash-project
Ich benutze ein
Makefile
für diesen Zweck:quelle