Hier ist mein Anwendungsfall: Das Befehlszeilenprogramm melt
kann einen Dateinamen mit der Erweiterung .melt
in der Befehlszeile akzeptieren und öffnen. Als Beispiel ist dies eine richtige test_p.melt
Datei:
colour:blue
out=24
colour:red
out=48
... die öffnet und spielt mit melt test_p.melt
.
Die Sache ist nun, dass .melt
Dateien keine Kommentare unterstützen, was ich mir wünschte (Sie erhalten Fehlermeldungen für jede Zeile, die ein nicht analysierbares Argument enthält, einschließlich solcher mit beispielsweise a #
). Also hier ist eine kommentierte test_c.melt
Datei:
# master comment here
colour:blue # this is blue!
out=24
colour:red
out=48
Wenn Sie dies melt
direkt öffnen, erhalten Sie:
$ melt test_c.melt
Failed to load "# master comment here"
...
... und es wird kein blauer Bildschirm angezeigt.
Also dachte ich mir - nun, ich kann trotzdem Kommentare einfügen und dann die Bash-Prozessersetzung verwenden, um die Datei zu filtern sed
, und diese einfach der melt
Anwendung zur Verfügung stellen. Zuerst habe ich einen Test mit versucht cat
, der erfolgreich ist:
$ cat <(sed 's/#.*$//' test_c.melt)
colour:blue
out=24
colour:red
out=48
... sieht gut aus; aber wenn ich das mit versuche, melt
sieht es durch meinen Trick:
$ melt <(sed 's/#.*$//' test_c.melt)
Failed to load "/dev/fd/62"
Failed to load "/dev/fd/62"
Grundsätzlich hat Melt den Dateinamen des Rohrs Bash erhalten, das für die Prozessersetzung bereitgestellt wurde - aber leider melt
wird es argv[i]
direkt verarbeitet . und im Falle einer Datei muss eine .melt
Erweiterung im Dateinamen angezeigt werden; Wenn dies nicht der Fall ist, schlägt der Prozess fehl.
Meine Frage lautet also: Wie könnte ich die Prozessersetzung verwenden - also hat der Dateiname der Pipe in diesem Fall eine bestimmte Erweiterung .melt
? Grundsätzlich möchte ich als Ergebnis der Substitution einen Pipe-Dateinamen von /dev/fd/62.melt
, von dem ich denke, dass er übergeben wird.
NB: Natürlich kann ich immer tun:
sed 's/#.*$//' test_c.melt > test_c_temp.melt
melt test_c_temp.melt
... aber zuerst gibt es hier zwei Befehle - und ich möchte eine einzeilige Pipeline; und zum anderen eröffnet es ein weiteres Problem, wenn ich darüber nachdenke, temporäre Dateien danach zu entfernen, was mir nicht gefällt.
Ist dies mit Bash-Prozessersetzung möglich - oder irgendwie mit Standard-Linux-Tools?
melt < <(sed 's/#.*$//' test_c.melt)
melt
kümmert es mich nicht um Befehle, die durchgeleitet werdenstdin
, da ich:Usage: melt [options] [producer [name=value]* ]+
und einen Speicherauszug von Programmoptionen bekomme . Prost!man melt
für dich lesen . " Wenn keine Dateien angegeben sind, wird die Komprimierung auf die Standardeingabe angewendet ." Sosed 's/#.*$//' test_c.melt | melt > result.file
arbeiten können.melt
(MLT Melt 0.6.2; "Standardeingabe" wird in dieser Version nicht erwähntman melt
), da ich für diesen Befehl wiederUsage: melt [options] [producer [name=value]* ]+
und bekomme eine Müllkippe. Prost!man melt
auf Ihrer Maschine lesen . Wenn Sie keine Antwort finden können, posten Sie auf pastebin.com und posten Sie den Link hier.Antworten:
Eine Möglichkeit wäre,
melt
auf ein Dateisystem zu verweisen , das geänderte Kopien von Dateien anzeigt. FUSE ist eine generische Methode zum Erstellen eines Dateisystemtreibers, der von einem normalen Programm implementiert wird und keine Berechtigungen erfordert. Es gibt viele FUSE-Dateisysteme , und es besteht eine gute Chance, dass eines davon Ihnen helfen kann. Die Idee ist, einen Einhängepunkt bereitzustellen, an dem das Lesen einer.melt
Datei die „echte“ Datei liest, wobei jedoch Kommentare herausgefiltert werden.ScriptFS sieht vielversprechend aus (aber ich habe es nie benutzt). So etwas sollte funktionieren:
Wo
~/work
ist die Wurzel des Baums, der Ihre.melt
Dateien enthält und~/bin/uncomment-melt
istWenn Sie dann eine Datei
~/work/test_c.melt
mit Kommentaren haben, können Sie diese ausführenmelt ~/uncommented-melt/test_c.melt
.Andere potenziell hilfreiche FUSE-Dateisysteme:
quelle
scriptfs
zu arbeiten - hier ist ein Befehlsprotokoll ich zu der Zeit gespeichert (AFAICR, Stack an diesem Tag abgestürzt:)
) gist.github.com/anonymous/e9ee5e8c53d1b4c3c736 - so endete ich mit einem up -bash
Skript Ansatz, den ich geschrieben unten. Prost!Mit der
zsh
Shell können Sie die=(...)
Form der Prozessersetzung verwenden (bei der temporäre Dateien anstelle von/dev/fd/x
Dateien und Pipes verwendet werden), für die Sie ein Suffix angeben können:Weitere Informationen finden Sie unter
info zsh TMPSUFFIX
(vorausgesetzt, dieinfo
Seiten sind installiert, Sie müssen möglicherweise einzsh-doc
Paket installieren ).quelle
Ok, es stellt sich heraus, dass in meinem speziellen Fall diese Art von Schmelzskripten streng als Befehlszeilenargumente zu interpretieren sind. Nur der
sed
im OP schneidet es also nicht ganz ab (außerdem gibt es andere Dinge wie Profile, die eingestellt werden können). Hier ist also, was ich letztendlich getan habe - kann wahrscheinlich als Inspiration in anderen Fällen dienen, die der Titel des OP abdecken würde.Ich habe mich schließlich dazu entschlossen: eine
test.shmelt
Datei zu erstellen, die eigentlich einbash
Skript ist, das meinen kommentiertenmelt
Skriptcode enthält; diese Datei ausführbar machenchmod +x test.shmelt
; Führen Sie das Skript nach dem Bearbeiten als aus./test.shmelt
.Beim Ausführen wird eine "bereinigte"
test.melt
Datei erstellt/tmp
undmelt
stattdessen diese Datei aufgerufen . Damelt
diese temporäre Datei normalerweise nach dem Ende des Programms im Terminal weiter ausgeführt wird, kann diese temporäre Datei mit einem Trap auf SIGINT bereinigt werden, wenn Strg-C gedrückt wird (muss aber nicht).Auf diese Weise habe ich noch Kommentare; kann schnell in der Quelldatei bearbeiten und Melt ausführen und Ergebnisse anzeigen; und habe eine Datei "bereinigt" von Kommentaren, die ich später verwenden kann.
Hier ist der Code von
test.shmelt
:quelle
Es ist eine Weile her, aber ich werde versuchen, die Titelfrage auf eine Weise zu beantworten, die für mich nützlich gewesen wäre.
Dies hängt zusammen: Warum funktioniert die BASH-Prozessersetzung bei einigen Befehlen nicht?
Das spezifische Problem, das ich zu lösen versuchte, war folgendes:
convert
.Leider gibt das Tool nicht gerne in stdout / fds / pipes aus, da es das Ausgabeformat von der Erweiterung des Ausgabedateinamens ableitet. Also, wie man es austrickst?
Erstellen Sie einen Softlink mit der entsprechenden Erweiterung
/dev/fd/N
und verwenden Sie diesen als "temporäre Datei".Beispiel:
quelle