Ich habe ein Black-Box-UNIX-Programm, das in einer Bash-Shell verwendet wird, das Datenspalten aus stdin liest, sie verarbeitet (einen Glättungseffekt anwendet) und dann auf stdout ausgibt. Ich benutze es von UNIX-Pipes, wie
generate | smooth | plot
Für mehr Glättung kann ich das Glätten wiederholen, damit es von der Bash-Befehlszeile als aufgerufen wird
generate | smooth | smooth | plot
oder auch
generate | smooth | smooth | smooth | smooth | smooth | smooth | smooth | smooth | smooth | smooth | plot
Das wird unübersichtlich. Ich möchte einen Bash-Wrapper so gestalten, dass er smooth
seine Ausgabe smooth
beliebig oft in eine neue Instanz zurückspeist
generate | newsmooth 5 | plot
Anstatt von
generate | smooth | smooth | smooth | smooth | smooth | plot
Mein erster Versuch war ein Bash-Skript, das temporäre Dateien im aktuellen Verzeichnis generierte und löschte, das sich jedoch als hässlich erwies, wenn ich mich nicht in einem Verzeichnis mit Schreibzugriff befand, und bei Unterbrechung auch Mülldateien hinterließ.
Es gibt keine Argumente zum smooth
Programm.
Gibt es eine elegantere Möglichkeit, ein solches Programm zu "verpacken", um die Anzahl der Aufrufe zu parametrisieren?
quelle
Antworten:
Sie könnten es in eine rekursive Funktion einschließen:
Sie würden dies als verwenden
das wäre äquivalent zu
quelle
Wenn Sie es sich leisten können, so viele Kommas wie
smooth
möglich einzugeben, können Sie die durch Kommas getrennte Klammererweiterung der Shell nutzen.TL; DR
Die gesamte Befehlszeile für Ihren Beispielfall lautet:
Hinweis:
smooth |
|
vorher,plot
da dies in der letztensmooth |
von der Brace Expansion produzierten Saite enthalten istsmooth
, sofern Sie sie korrekt in den angegebenen festen Teil einfügen können, der der offenen Klammer vorausgeht. Denken Sie auf jeden Fall daran, dass Sie sie für alle Wiederholungen des Befehls bereitstellen würdenWie es funktioniert
Mit der durch Kommas getrennten geschweiften Klammer können Sie dynamisch Zeichenfolgen erstellen, die jeweils aus einem festgelegten Teil und den festgelegten variablen Teilen bestehen. Es werden so viele Zeichenfolgen
a{b,c,d}
erzeugt , wie variable Teile angegeben sind, wie es produziert wirdab ac ad
.Der kleine Trick dabei ist, dass die Klammererweiterung nur Kopien des festen Teils erzeugt , wenn Sie lieber eine Liste leerer variabler Teile erstellen, dh nur mit Kommas in den Klammern. Zum Beispiel:
wird herstellen:
Beachten Sie, dass 4 Kommas 5
smooth
Zeichenfolgen ergeben. So funktioniert diese Klammer-Erweiterung: Sie erzeugt Strings mit so vielen Kommas plus einem.Natürlich benötigen Sie in Ihrem Fall auch jeweils eine
|
Trennung.smooth
Fügen Sie sie also einfach in den festen Teil ein, und achten Sie darauf, dass Sie sie richtig zitieren, damit die Shell sie nicht sofort interpretiert. Das ist:wird herstellen:
Achten Sie darauf, dass Sie das feststehende Teil immer unmittelbar neben der offenen Stütze platzieren, dh es dürfen keine Abstände zwischen der
'
und der{
.(Beachten Sie auch, dass Sie zur Bildung des festen Teils auch doppelte Anführungszeichen anstelle von einfachen Anführungszeichen verwenden können, wenn Sie Shell-Variablen im festen Teil erweitern müssen. Achten Sie nur auf das zusätzliche Escape-Zeichen, das erforderlich ist, wenn einige Shell-Sonderzeichen auftreten in doppelten Anführungszeichen).
An dieser Stelle benötigen Sie eine
eval
auf diesen String angewendeten Befehl ausführen, damit die Shell ihn schließlich als den Pipeline-Befehl interpretiert, den sie haben soll.Zusammenfassend wäre die gesamte Befehlszeile für Ihren Beispielfall also:
quelle
eval
nicht vertrauenswürdigen, nicht bereinigten Zeichenfolgen zu Bewertungszwecken zu, d. H. Bei der Verwendung mit Variablen, die möglicherweise "unbekannten" Inhalt wie den von Ihnen verknüpften enthalten. Auf der anderen Seiteeval
kann es auch sehr praktisch sein, Befehle schnell zu "säubern", insbesondere wenn sie an der Eingabeaufforderung verwendet werden, wie es der Fall zu sein scheint, bei demeval
die Eingabe nur aus einer vom Benutzer manuell eingegebenen Zeichenfolge besteht Personeval str
etwas anmaßendes & dummes ersetzen. /dev/stdin <<<str
. Dies wird nicht nur einen Eindruck auf die Narren hinterlassen, es wird auch @CharlesDuffy von deinem Rücken abhalten ;-)