Ich habe eine Menge Fragen, Antworten und Kommentare bemerkt, die meine Verachtung zum Ausdruck bringen (und manchmal sogar Angst davor haben), Skripte anstelle von Einzeilern zu schreiben. Also, ich würde gerne wissen:
Wann und warum sollte ich ein eigenständiges Skript schreiben und nicht einen "Einzeiler"? Oder umgekehrt?
Was sind die Anwendungsfälle und Vor- und Nachteile von beiden?
Sind einige Sprachen (zB awk oder perl) besser für Einzeiler geeignet als andere (zB Python)? Wenn ja warum?
Ist es nur eine Frage der persönlichen Präferenz oder gibt es gute (dh objektive) Gründe, unter bestimmten Umständen das eine oder andere zu schreiben? Was sind diese Gründe?
Definitionen
one-liner
: Eine beliebige Folge von Befehlen, die direkt in eine Shell-Befehlszeile eingegeben oder eingefügt werden . Oft die Rohrleitungen und / oder die Verwendung von Sprachen wiesed
,awk
,perl
und / oder Tools wiegrep
odercut
odersort
.Es ist die direkte Ausführung auf der Kommandozeile, die das bestimmende Merkmal ist - die Länge und Formatierung ist irrelevant. Ein "Einzeiler" kann sich alle in einer Zeile befinden oder mehrere Zeilen umfassen (z. B. sh for loop oder eingebetteter awk- oder sed-Code mit Zeilenvorschub und Einzug zur Verbesserung der Lesbarkeit).
script
: Eine beliebige Folge von Befehlen in einer oder mehreren interpretierten Sprachen, die in einer Datei gespeichert und dann ausgeführt werden. Ein Skript kann vollständig in einer Sprache geschrieben sein, oder es kann ein Shell-Skript-Wrapper sein, der mehrere "Einzeiler" in anderen Sprachen verwendet.
Ich habe meine eigene Antwort (die ich später veröffentlichen werde), aber ich möchte, dass dies eine kanonische Frage und Antwort zu diesem Thema ist, nicht nur meine persönliche Meinung.
Antworten:
Eine weitere Antwort, die auf praktischen Erfahrungen basiert.
Ich würde einen Einzeiler verwenden, wenn es sich um "Wegwerf" -Code handelt, den ich direkt an der Eingabeaufforderung schreiben könnte. Zum Beispiel könnte ich dies verwenden:
Ich würde ein Skript verwenden, wenn ich der Meinung wäre, dass es sich lohnt, den Code zu speichern. An dieser Stelle würde ich eine Beschreibung oben in die Datei einfügen, wahrscheinlich einige Fehlerprüfungen hinzufügen und sie möglicherweise sogar in ein Code-Repository für die Versionsverwaltung einchecken. Wenn ich zum Beispiel entschied, dass das Überprüfen der Betriebszeit einer Reihe von Servern eine nützliche Funktion ist, die ich immer wieder verwenden würde, könnte der obige Einzeiler folgendermaßen erweitert werden:
Verallgemeinernd könnte man sagen
Einzeiler
Skript
cron
)Ich sehe eine ganze Reihe von Fragen hier unter Unix. SE bittet um einen Einzeiler , um eine bestimmte Aufgabe auszuführen. Anhand meiner obigen Beispiele denke ich, dass das zweite viel verständlicher ist als das erste, und daher können die Leser mehr daraus lernen. Eine Lösung kann leicht von der anderen abgeleitet werden. Aus Gründen der Lesbarkeit (für zukünftige Leser) sollten wir daher wahrscheinlich vermeiden, Code in einer Zeile für etwas anderes als die trivialsten Lösungen bereitzustellen.
quelle
set -- host1 host2 host3
dannfor h in "$@"
(oder auch nurfor h
) das Skript POSIX-portabel machen. :-)Schreiben Sie ein Skript, wenn:
Schreiben Sie einen Einzeiler, wenn:
quelle
Wenn eine erforderliche Reihe von Befehlen relativ kurz ist und / oder ein Ergebnis liefert, das als Teil einer größeren Pipeline oder eines Befehls-Alias verwendet werden kann, ist dies möglicherweise ein guter Einzeiler.
Grundsätzlich denke ich, dass Einzeiler normalerweise Dinge sind, die ein erfahrener Systemadministrator, der sowohl mit dem Problem als auch mit den verwendeten Befehlen vertraut ist, an Ort und Stelle schreiben kann, ohne zu viel nachzudenken.
Wenn ein Einzeiler übermäßig lang wird oder mehr als nur sehr einfache Bedingungen oder Schleifen enthält, ist es normalerweise aus Gründen der Lesbarkeit besser, sie als mehrzeiliges Skript oder als Shell-Funktion zu schreiben. Wenn es sich um etwas handelt, das Sie schreiben, um es immer wieder zu verwenden, oder um etwas, das von anderen Leuten verwendet wird (und möglicherweise Probleme verursacht), sollten Sie bereit sein, sich die Zeit zu nehmen, um die Lösung in ein klares (er) zu schreiben. Skriptform.
In Python ist Einrückung Teil der Syntax, sodass Sie die Funktionen der Sprache nicht in vollem Umfang nutzen können, wenn Sie einen Einzeiler schreiben.
Perl- und awk-Einzeiler verwenden häufig die rohe Kraft regulärer Ausdrücke. Aber einige nennen reguläre Ausdrücke eine Nur-Schreiben-Sprache, nicht ganz ohne Grund. Wenn Sie ein mehrzeiliges Skript schreiben, können Sie Kommentare schreiben, um zu beschreiben, was ein bestimmter regulärer Ausdruck tun soll. Dies ist sehr hilfreich, wenn Sie das Skript erneut ansehen, nachdem Sie sechs Monate lang andere Aufgaben ausgeführt haben.
Dies ist von Natur aus eine sehr meinungsbasierte Frage, da gemessen werden muss, welche Komplexität akzeptabel ist, und ein Kompromiss zwischen Lesbarkeit und Kompaktheit gefunden werden muss. All dies ist eine Frage der persönlichen Beurteilung. Sogar die Wahl einer Sprache kann von persönlichen Dingen abhängen: Wenn eine bestimmte Sprache theoretisch für ein bestimmtes Problem optimal wäre, Sie sie jedoch nicht kennen und bereits wissen, wie Sie das Problem mit einer anderen Sprache lösen können, können Sie die auswählen vertraute Sprache, um den Job schnell und mit minimalem Aufwand erledigen zu können, obwohl die Lösung technisch möglicherweise etwas ineffizient ist.
Das Beste ist oft der Feind des Guten , und das gilt hier sehr.
Und wenn Sie mit Perl vertraut sind, haben Sie vielleicht bereits von TMTOWTDI gehört: Es gibt mehr als eine Möglichkeit, dies zu tun.
quelle
Bitte beachten Sie, dass dies eine persönliche Meinung ist; Nimm es mit einem Körnchen Salz.
Wenn der Befehl beispielsweise aus 80 Zeichen besteht, verwenden Sie einen Einzeiler. Lange Befehlszeilen sind schwer zu bearbeiten. Es gibt auch das Problem der Wiederholung, siehe # 2
Wenn Sie die Befehle mehrmals ausführen müssen, verwenden Sie ein Skript. Verwenden Sie andernfalls einen Einzeiler, sofern die Bedingung Nr. 1 erfüllt ist.
quelle
Ich betrachte und benutze einen Einzeiler als temporäres Entwicklungswerkzeug, um wiederholt zu bearbeiten, bis er das tut, was ich will, oder ich verstehe, wie subtil ein Unterbefehl funktioniert.
Es wird dann entweder in einer Textdatei zu dem Thema, das ich untersucht habe, notiert (und mit Anmerkungen versehen) oder in einem Skript aufgeräumt, das in meinem persönlichen Bin PATH abgelegt wird, möglicherweise zur weiteren Verfeinerung, Parametrisierung und so weiter. Normalerweise wird die eine Zeile besser lesbar, auch wenn keine anderen Änderungen vorgenommen werden oder ich das Skript nie wieder verwende.
Ich habe meinen Shell-Verlauf auf über 5000 Zeilen festgelegt, mit einem separaten Verlauf pro Terminal und pro Anmeldung auf einer Fernbedienung und so weiter. Ich hasse es, in diesen Geschichten keinen einzeiligen Befehl zu finden, den ich vor ein paar Wochen entwickelt habe und dachte nicht, dass ich ihn noch einmal brauchen würde, daher meine Strategie.
Manchmal muss eine ganze Gruppe von Befehlen etwas tun, z. B. Hardware konfigurieren. Am Ende kopiere ich sie alle aus dem Verlauf, bereinige sie minimal und füge sie einem Shell-Skript hinzu,
RUNME
genau wie meine Notizen, aber auch so, dass sie fast bereit sind, von jemand anderem wieder verwendet zu werden. (Aus diesem Grund finde ich Tools, die nur eine grafische Benutzeroberfläche bieten, um diese zu konfigurieren.) Ich finde, dass dies einen unglaublichen Effizienzgewinn darstellt, da so oft etwas, von dem Sie erwarten, dass es nur einmal ausgeführt wird, dann noch fünf Mal ausgeführt werden muss. .quelle
ln
vs.ln -s
for hard vs. soft links in einem Einzeiler, der sich über einige Dateien erstreckt.Ich möchte, dass die Mitarbeiter in meinem Team Skripte für alle Vorgänge schreiben, die möglicherweise mehrmals ausgeführt werden müssen (z. B. "Workflows" oder "Pipelines"), und für alle einmaligen Aufgaben, die dokumentiert werden müssen (normalerweise) Dinge wie "bestimmte Dinge in einem Datensatz ändern, um falsch gelieferte Daten zu korrigieren" in unserem Fall). Abgesehen davon spielen "Einzeiler" oder Skripte keine große Rolle.
Wenn Workflows (als Skripte oder Ähnliches) nicht ordnungsgemäß dokumentiert werden, ist es schwieriger, neue Mitarbeiter in ein Projekt einzuführen, und es ist auch schwieriger, Mitarbeiter aus einem Projekt zu entfernen. Es erschwert außerdem jede Art von Prüfung, und das Aufspüren von Fehlern kann unmöglich sein.
Dies ist unabhängig davon, welche Sprache für die Programmierung verwendet wird.
An anderen Arbeitsplätzen kann es zu ähnlichen / anderen Bräuchen oder Erwartungen kommen, die möglicherweise sogar niedergeschrieben werden.
Zu Hause tun Sie, worauf Sie Lust haben.
Zum Beispiel schreibe ich Skripte, sobald ich etwas Nicht-Triviales in der Shell mache , etwa bevor ich eine Antwort auf eine U & L-Frage abschicke, oder wenn ich die einzelnen Komponenten eines Befehls oder Befehlssatzes testen muss, bevor ich ihn ausführe " Real".
Ich schreibe auch Skripte für sich wiederholende Aufgaben, die ich jedes Mal auf die gleiche Weise ausführen möchte, auch wenn sie einfach sind
Ich benutze Shell - Funktionen (sehr selten Aliase) für Bequemlichkeit in interaktiver Shells, zB Optionen auf bestimmte Befehle standardmäßig hinzufügen (
-F
fürls
) oder für spezialisierte Variationen einiger Befehle zu schaffen (pman
hier ist einman
Befehl , dass nur Blicke auf POSIX - Handbuch, zum Beispiel) .quelle
Sieht so aus, als ob ich diesbezüglich eine Minderheitssicht habe.
Der Begriff "Drehbuch" ist absichtlich verwirrend, werde es los. Dies ist Software, die Sie dort schreiben, auch wenn Sie ausschließlich
bash
und verwendenawk
.Innerhalb eines Teams schreibe ich lieber Software mit einem Code-Review-Prozess, der von einem Tool (github / gitlab / gerrit) erzwungen wird. Dies gibt Versionskontrolle als Bonus. Wenn Sie über mehrere Systeme verfügen, fügen Sie fortlaufende Bereitstellungstools hinzu. Und einige Testsuiten, wenn die Zielsysteme wichtig sind. Ich bin nicht religiös, aber wiegen Sie die Vorteile und Kosten.
Wenn Sie ein Team von Administratoren haben, ist das einfachste
vim /root/bin/x.sh
meist eine Katastrophe in Bezug auf veränderungsbezogene Kommunikation, Codelesbarkeit und systemübergreifende Verteilung. Oft kostet eine schwerwiegende Störung mehr Zeit / Geld als der vermeintlich "schwere" Prozess.Ich bevorzuge Einzeiler eigentlich für alles, was diesen "schweren" Prozess nicht verdient. Sie können mit wenigen Tastenanschlägen schnell wiederverwendet werden, wenn Sie wissen, wie Sie den Shell-Verlauf effektiv nutzen können. Einfügen zwischen unabhängigen Systemen (z. B. verschiedenen Kunden).
Entscheidender Unterschied zwischen (nicht überprüften!) Einzeilern und der getesteten Software ("Skripte"): Die Verantwortung liegt vollständig bei Ihnen, wenn Sie Einzeilern ausführen. Man kann nie zu sich selbst sagen : „Ich habe gerade diese Einzeiler irgendwo, ich lief es ohne zu verstehen, gefolgt was nicht meine Schuld“ - Sie wüssten , dass Sie nicht überprüft und nicht getestete Bit-of-Software ausgeführt wird , so dass es ist deine Schuld. Stellen Sie sicher, dass es klein genug ist, damit Sie die Ergebnisse vorhersehen können - seien Sie verdammt, wenn Sie dies nicht tun.
Manchmal ist dieser vereinfachte Ansatz erforderlich, und das Setzen des Balkens auf ungefähr eine Textzeile ist in der Praxis gut geeignet (dh die Grenze zwischen überprüftem und nicht überprüftem Code). Einige meiner Einzeiler sehen furchtbar lang aus, aber sie funktionieren effektiv für mich. Solange ich sie grobe und es nicht mehr jungen Kollegen anvertraue, ist alles in Ordnung. In dem Moment, in dem ich sie teilen muss, durchlaufe ich den Standard-Software-Entwicklungsprozess.
quelle
Ich muss sagen, ich bin etwas entsetzt über die Implikationen der ersten Teile der Frage. Die Unix-Skriptsprachen sind vollwertige Programmiersprachen, und Programmiersprachen sind Sprachen , was bedeutet, dass sie so unendlich formbar und flexibel sind wie menschliche Sprachen. Und eines der Kennzeichen von "unendlicher Formbarkeit und Flexibilität" ist, dass es fast nie "einen richtigen Weg" gibt, etwas auszudrücken - es gibt verschiedene Wege, und das ist gut so! Ja, natürlich ist es eine Frage der persönlichen Präferenz, und daran ist nichts auszusetzen. Wer sagt, dass es nur einen Weg gibt, etwas zu tun,
Es war einmal, mein eigenes
~/bin
war voll von „nützlichen“ kleine Skripte ich geschrieben hatte. Aber mir wurde klar, dass die meisten von ihnen sich an dem Tag, an dem ich sie schrieb, daran gewöhnt hatten und nie wieder. Je mehr Zeit vergeht, desto kleiner wird meinbin
Verzeichnis.Ich glaube nicht, dass irgendetwas falsch daran ist , ein Drehbuch zu schreiben. Wenn Sie sich vorstellen, dass Sie oder jemand anderes es auf jeden Fall wieder verwenden könnte, schreiben Sie ein Skript. Wenn Sie ein unterstützendes Skript "richtig konstruieren" möchten, tun Sie dies auf jeden Fall. (Auch wenn niemand es jemals benutzt, ist es eine gute Übung, es zu schreiben.)
Gründe, warum ich weniger Skripte schreibe (und "Einzeiler" favorisiere):
bin
Verzeichnisverwirrung hat Kosten. Ich lege keine Dinge mehr dorthin, es sei denn, sie gehören wirklich dorthin.quelle
Ich glaube, dass die Anfrage nach einem "Einzeiler" die meiste Zeit tatsächlich eine Anfrage nach einem "gesunden Biss" ist, das heißt:
Die Benutzer möchten und fordern den kürzesten Code an, der eine Lösung für die gestellte Frage darstellt.
Manchmal gibt es keine Möglichkeit, eine Rede auf einen "Sound Bite" zu reduzieren, und es kann unmöglich sein, ein Skript auf einen kurzen "Einzeiler" zu reduzieren. In solchen Fällen ist die einzig mögliche Antwort ein Skript.
Und im Allgemeinen ist ein "Klangbiss" niemals ein guter Ersatz für die gesamte Rede. Ein "Einzeiler" ist also im Allgemeinen nur gut, um eine Idee zu vermitteln oder ein praktisches Beispiel für diese Idee zu geben. Nachdem die Idee verstanden wurde, sollte sie in einem Skript erweitert (angewendet) werden.
Schreiben Sie also einen "Einzeiler", um eine Idee oder ein Konzept zu vermitteln.
Schreiben Sie Ihren allgemeinen Code als vollständige Skripte und nicht als Einzeiler.
quelle
Sie fragen nach "Angst und Verachtung von Skripten". Dies liegt an der Frage-und-Antwort-Situation, in der häufig die Antwort lautet: Dieser und der folgende Schritt sind erforderlich, ich kann ihn jedoch auch in eine Zeile setzen (Sie können ihn also kopieren, einfügen und als langen einfachen Befehl verwenden).
Manchmal kann man nur raten, ob das Q durch eine schnelle und schmutzige Kopier-Einfügelösung besser bedient wird oder ob ein "nettes" Skript genau das ist, was das Q verstehen muss.
Viele der Vor- und Nachteile hier sind wahr, aber sie verfehlen immer noch den Punkt. Ich würde sogar sagen, dass die Definitionen im Q nicht hilfreich sind.
Die Shell- Verlaufsdateien sind "Einzeiler", werden aber trotzdem gespeichert. Mit der Bash-Funktion
operate-and-get-next (C-o)
können Sie sie sogar halbautomatisch wiederholen.Ich sehe kaum das Wort Funktion erwähnt. Auf diese Weise können sowohl "Skripte" als auch "Einzeiler" gespeichert werden. Mit wenigen Tastendrücken können Sie zwischen beiden Formaten wechseln. Ein zusammengesetzter Befehl kann oft zu beiden passen.
history -r file
Mit dieser Option können Sie eine oder mehrere Befehlszeilen (und Kommentare) aus einer beliebigen Datei lesen, nicht nur aus einer Standardverlaufsdatei. Es bedarf nur einer minimalen Organisation. Sie sollten sich nicht auf eine große Größe der Verlaufsdatei und die Verlaufssuche verlassen, um (einige) Versionen einer Befehlszeile abzurufen.Funktionen sollten auf ähnliche Weise definiert werden. Legen Sie für den Anfang
thisfunc() {...}
eine Datei "functions" in Ihr Ausgangsverzeichnis und geben Sie sie als Quelle ein. Ja, das ist ein gewisser Aufwand, aber es ist die allgemeine Lösung.Wenn Sie jede Befehlszeile und jede Skriptvariante in einer separaten Datei speichern, ist dies eine (theoretische, aber objektive) Verschwendung von Dateisystemblöcken.
Ein Einzeiler hat nichts schnelles und schmutziges an sich. Es ist eher der Teil zum Kopieren und Einfügen, der ein bisschen verpönt ist, und wie wir uns einfach auf den Befehlsverlauf verlassen, um ihn für uns zu speichern.
@sitaram: dein one liner hat wirklich un-onelinerish features: shebang line, newline, vier utility calls - zwei davon sed "programme". Ich denke, dass das ursprüngliche Perl-Skript besser aussah und schneller lief und keine Bytes verschwendete, indem es sich auf 60 Zeilen verteilte. Und mit Perl können Sie auch einiges auspressen.
Für mich ist das genau die Art von Einzeiler, die man vermeiden sollte. Möchten Sie das (eingefügt) auf Ihrer Befehlszeile haben? Nein, und wenn Sie es trotzdem in einer Datei speichern (unabhängig von Skript oder Funktion), investieren Sie möglicherweise zwei oder drei Zeilenvorschubbytes, damit es gut aussieht.
10 Minuten. später: ich wollte nur überprüfen, ob ich "zwei sed programme" sagen kann oder ob es sich um "zwei sed ersetzungen / aufrufe" handelt. Aber die Antwort von Sitaram ist weg. Meine Antwort macht immer noch Sinn, hoffe ich.
quelle