Benutzerkonfiguration eines Shell-Skripts. Empfohlene Vorgehensweise?

13

Ich schreibe ein Shell-Skript mit ein paar Variablen, die vom Benutzer konfiguriert werden sollten. Es wird ein Installationsprogramm zum Herunterladen und Konfigurieren des Skripts geben, möglicherweise durch eine Reihe von Fragen. Das betreffende Skript richtet sich an andere Entwickler.

Dies kann auf verschiedene Arten implementiert werden:

  1. Verwenden Sie Platzhalter im Skript selbst und sedersetzen Sie diese während der Installation (in etwa so: /programming/415677/how-to-replace-placeholders-in-a-text-file )

    • Vorteile: Alle Variablendefinitionen sind im Skript enthalten. Es ist einfach, das Skript manuell herunterzuladen und die Variablen für Benutzer zu konfigurieren, die einen Editor gegenüber dem Installationsprogramm bevorzugen.

    • Nachteile: Es ist schwierig, die Variablen über das Installationsprogramm neu zu konfigurieren, sobald sie vorhanden sind. Es sei denn, ich erstelle eine komplexere reguläre Ausdrucksweise, die fehleranfällig wäre.

  2. Verwenden Sie eine Konfigurationsdatei , im Grunde ein anderes Shell-Skript mit Zuweisungen, und verwenden Sie diese source, um sie einzuschließen. (Und wahrscheinlich legen Sie es in ~/.scriptname? Das Hauptskript wird kopiert /usr/local/bin)

    • Vorteile: Es ist einfach, das Skript neu zu konfigurieren. Es könnte sogar ein Parameter aus dem Hauptskript hinzugefügt werden. (Funktioniert wahrscheinlich auch in der ersten Lösung, aber das Bearbeiten eines Skripts von sich aus klingt nicht nach einer sehr guten Idee.)

    • Nachteile: Das Skript ist jetzt von zwei Dateien abhängig und der Benutzer muss das Installationsprogramm ausführen, damit die Konfigurationsdatei erstellt wird. Dies kann behoben werden, indem automatisch eine Konfigurationsdatei generiert wird, falls keine vorhanden ist. Das Auffinden einer externen Konfigurationsdatei ist jedoch für Benutzer, die das Skript nur herunterladen, bearbeiten und fertigstellen möchten, noch umständlicher.

Außerdem einige Optionen, wie die Konfiguration nach der Installation vom Benutzer verwaltet werden soll:

  1. Sie mögen
    $ myscript config server.host example.org $ myscript config server.proxypath / home / johndoe / proxy $ myscript config server.httppath / home / johndoe / web

  2. Interactive
    $ myscript config
    Geben Sie den Server-Hostnamen ein: example.org
    Geben Sie den Pfad zum Proxy auf dem Server ein: / home / johndoe / proxy
    Geben Sie den Pfad zum http-Verzeichnis auf dem Server ein: / home / johndoe / web

  3. getopts with long options
    $ myscript --host example.org --proxypath / home / johndoe / proxy --httppath / home / johndoe / web

  4. Einfache
    $ myscript config example.org / home / johndoe / proxy / home / johndoe / web

Gibt es andere Möglichkeiten, dies zu tun, die Sie in Betracht ziehen würden?
Irgendwelche Best Practices, irgendetwas Elegantes?

Charlie Rudenstål
quelle
2
Ich bezweifle nicht, dass Sie ein Shell-Skript schreiben können , das all dies tut, aber die Frage ist, warum Sie etwas so Komplexes schreiben möchten, dass ein Installer in einem Shell-Skript erforderlich ist. Wie auch immer, sehen Sie sich an, wie das Linux-Kernel-Konfigurationssystem seine Konfigurationsdatei verwaltet.
Gut. Das Installationsskript lädt nur das eigentliche Skript herunter, kopiert es an den richtigen Speicherort und stellt eine Reihe von Fragen zur Konfiguration (3-4 Variablen). Auf diese Weise kann ich den Benutzern eine einzige Befehlszeile geben, indem ich das Installationsskript wgetting und es nach / bin / sh leiten lasse. Natürlich könnte ich den Installer überspringen und einfach einen 'install'-Parameter zum Hauptskript hinzufügen. Vielleicht eine bessere Lösung, was denkst du?
Charlie Rudenstål
"Aber die Frage ist, warum Sie etwas so Komplexes schreiben möchten", lautet das fragliche Skript: github.com/charlie-rudenstal/depo Ich versuche, die Anzahl der Schritte zu reduzieren, die neue Benutzer ausführen müssen, insbesondere während der Installation. Prüfen Sie, ob das erforderliche Server-Setup auch automatisch durchgeführt werden kann.
Charlie Rudenstål

Antworten:

6

Was würde ich von einem vernünftigen Programm erwarten (ein Shell-Skript oder nicht):

  • Ich muss die ausführbare Datei nie ändern, um sie nur zu konfigurieren. Dies ist kein Betriebssystemkernel.
  • Ich kann jede Einstellung über die Befehlszeile übergeben. Dies ist ein Muss für jede Information, die keinen angemessenen Standard hat. Die einzige Ausnahme ist ein Passwort, für das eine interaktive Eingabe erforderlich ist.
  • Optional kann ich eine Einstellung mithilfe einer Umgebungsvariablen übergeben.
  • Ich kann die Einstellungen in eine Konfigurationsdatei schreiben. Diese Datei wird verwendet, wenn sie unter einem bekannten Namen vorhanden ist oder explizit auf die Verwendung der beiden oben genannten Methoden hingewiesen wird.
  • Die Konfigurationsdatei verwendet dieselben Einstellungsnamen und dieselbe Syntax wie die Befehlszeile.
9000
quelle
Guter Rat. Wäre dies Ihre bevorzugte Bestellung? (1) Übergebene Einstellungen in der Befehlszeile prüfen (2) Einstellung in einer .scriptnameConfig im selben Verzeichnis prüfen (3) Einstellung in einer Umgebungsvariablen prüfen (4) Einstellung in einer .scriptnameConfig in ~ / .scriptnameConfig prüfen (5) Standard verwenden Einstellung
Charlie Rudenstål
"Die Konfigurationsdatei verwendet dieselben Einstellungsnamen und dieselbe Syntax wie die Befehlszeile." - Wie soll das aussehen? Ich wollte die Zuweisungssyntax für reguläre Shell-Skripte verwenden: SETTING = VALUE. Würde sich die Syntax eines Befehls in einer Konfigurationsdatei nicht etwas seltsam anfühlen?
Charlie Rudenstål
Sehen Sie, wie mountoder wie sshSie dieselbe Syntax in der Befehlszeile und in der Konfiguration verwenden können. Sie müssen die Befehlszeilensyntax nicht vollständig kopieren. anstelle von '--foo = bar' können Sie 'foo = bar' verwenden. Wenn Sie stattdessen 'BarOption: Foo' verwenden, ist dies weitaus weniger praktisch: Sie müssen sich merken, ob die Groß- / Kleinschreibung von Bedeutung ist, welches Schlüsselwort in der Datei und welches in der Befehlszeile akzeptiert wird und ob Sie keinen Arbeitsbefehl kopieren und einfügen können Zeile in eine Konfigurationsdatei mit nur kosmetischer Bearbeitung.
9000,
3

Wenn ich ein umfangreiches Skript mit verschiedenen Konfigurationsoptionen schreiben muss, verwende ich Python mit der argparse- und der ConfigParser- Bibliothek. Diese helfen bei der Implementierung, aber der Prozess gilt für jedes Shell-Skript:

  1. Suchen Sie nach einer Konfigurationsdatei. Wenn eine vorhanden ist, lesen Sie alle Einstellungen in eine Wörterbuch- / Nachschlagetabelle.
  2. Analysiert benannte Befehlszeilenargumente. Überschreiben Sie für jedes angegebene Argument den aus der Konfigurationsdatei geladenen Wert, falls vorhanden. Verwenden Sie für jedes Argument, das nicht in der Befehlszeile und nicht in der Konfiguration übergeben wird, eine Standardeinstellung.
  3. Führen Sie die Hauptfunktion des Skripts aus
  4. Wenn die Konfigurationsdatei nicht existiert, schreiben Sie die übergebenen und / oder Standardwerte darauf.

Ich bevorzuge, dass eine Konfigurationsdatei die bevorzugten Optionen enthält, wenn das Skript wiederholt verwendet wird, aber alle Befehlszeilenargumente außer Kraft gesetzt werden. Schreiben Sie die Konfigurationsdatei mit diesen Parametern, wenn sie zum ersten Mal ausgeführt wird. Die Konfigurationsdatei kann dann freigegeben und an ein Code-Repository übergeben werden.

In meinem letzten Fall habe ich auch die Standardeinstellungen in den [DEFAULT]Abschnitt oben in der Konfigurationsdatei geschrieben und dann einen Abschnitt für jede "Umgebung" mit entsprechenden Überschreibungen für jede. Die "Umgebung" ist der erste unbenannte Parameter des Skripts. Also in diesem Fall Parameter werden als gewähltes integrierten Standard -> Konfigurationsdatei Standard -> Konfigurationsdatei Abschnitt Wert -> Befehlszeilenparameter . Ein zusätzlicher Befehlszeilenparameter bietet die Möglichkeit, die vorhandene Konfiguration mit dem Wert des letzten Laufs zu überschreiben. Diese Konfigurationsdatei wird in das aktuelle Verzeichnis geschrieben, gilt also pro Projekt und kann mit dem Rest des Codes festgeschrieben werden. Jeder andere, der dasselbe Projekt auscheckt, startet dann mit derselben Konfiguration.

Matt S
quelle
Msgstr "Ein zusätzlicher Befehlszeilenparameter bietet die Möglichkeit, die vorhandene Konfiguration mit dem Wert des letzten Laufs zu überschreiben." Dies ist ein interessanter Ansatz. Eine praktische Möglichkeit, Parameter mit der Konfiguration zu kombinieren.
Charlie Rudenstål
+1, auch ich würde empfehlen, die Standardeinstellungen in a default.config Datei sich im selben Verzeichnis wie das Skript befindet, und dann nach einer Konfigurationsdatei unter ~/.scriptnamezu suchen , um diese Werte zu überschreiben. Auf diese Weise hat jeder Wert einen gültigen Standardwert und ist einfacher zu pflegen.
Aaron
2

Das Bearbeiten von Platzhaltern ist fehleranfällig.

Ich würde mit einer Config-Datei gehen.

Ihre Besorgnis über die Abhängigkeit ist berechtigt, ich kann mich jedoch nicht erinnern, zu viele Tools verwendet zu haben, die aus einer einzelnen Datei bestehen. Theoretisch sind Sie also richtig, aber praktisch sollte es ganz in Ordnung sein.

EIN dritte Option besteht darin, die Konfigurationssoftware zu veranlassen, eine neue angepasste Version zu schreiben , die für die ausgewählten Optionen und Parameter spezifisch ist. Das kann natürlich schwieriger zu schreiben und zu testen sein :)

Keine Chance
quelle