Ein normaler Tar-Befehl
tar cvf foo.tar ./foo >foo.out 2>foo.err
hat drei Ausgangs-E / A-Streams
- Daten in foo.tar archivieren
- Liste der Dateinamen zu STDOUT (umgeleitet in foo.out)
- Fehlermeldungen an STDERR (umgeleitet in foo.err)
Ich kann dann foo.err auf Fehlermeldungen untersuchen, ohne die Liste der Dateinamen durchlesen zu müssen.
Wenn ich etwas mit den Archivdaten machen möchte (durch Netcat oder ein spezielles Komprimierungsprogramm leiten), kann ich die -f -
Option von tar verwenden
tar cvf - ./foo 2>foo.err | squish > foo.tar.S
Aber jetzt ist meine Liste der Dateinamen mit meinen Fehlermeldungen gemischt, da die -v
Ausgabe von tar offensichtlich nicht an STDOUT gehen kann (dort fließen die Archivdaten), so dass tar dies geschickt in STDERR schreibt.
Mit der Korn-Shell können Sie einen Befehl erstellen, der den Archivdatenstrom an einen anderen Befehl weiterleitet und die -v
Ausgabe dennoch getrennt von Fehlermeldungen erfasst .
tee
? Dies scheint ein ziemlich gültiger Anwendungsfall dafür zu sein.Antworten:
Wenn Ihr System unterstützt
/dev/fd/n
:Was Sie mit AT & T-Implementierungen von
ksh
(oderbash
oderzsh
) mithilfe von Prozesssubstitution schreiben könnten :Das ist genau das Gleiche, außer dass diesmal die Shell entscheidet, welcher Dateideskriptor anstelle von
3
(normalerweise über 9) verwendet werden soll. Ein weiterer Unterschied besteht darin, dass Sie diesmal den Exit-Status vontar
anstelle von erhaltensquish
. Auf Systemen, die dies nicht unterstützen/dev/fd/n
, greifen einige Shells möglicherweise auf Named Pipes für diese Funktion zurück.Wenn Ihr System dies nicht unterstützt
/dev/fd/n
oder Ihre Shell Named Pipes nicht für die Prozessersetzung verwenden kann, müssen Sie Named Pipes von Hand bearbeiten .quelle
Dafür müssen Sie eine Named Pipe verwenden.
Erstellen Sie zuerst eine im Ordner:
Verwenden Sie dann diesen Befehl:
Hinweis: Der
cat
-part kann jetzt auch seingzip
oder was auch immer, der aus einer Pipe lesen kann:Erläuterung:
Der Ausgang ist mit dem Namen Rohr (geschrieben
foo.pipe
), wo eine andere Proccess (cat
,gzip
,netcat
) liest aus. Sie verlieren also nicht die stdout / stderr-Kanäle, um Informationen zu erhalten.quelle
umask 077
(oder verwenden Sie ein privates temporäres Verzeichnis) fest, um zu verhindern, dass andere Prozesse darauf lesen oder schreiben (auf vielen Systemen werden Named Pipes wie andere Dateien standardmäßig weltweit lesbar erstellt). 2) Sie müssen dies sicherstellen Die Named Pipe wird nur von jeder Instanz Ihres Skripts verwendet (wieder hilft ein einmaliges privates temporäres Verzeichnis). 3) Das bedeutet, dass Sie danach oder bei Unterbrechung bereinigen müssen.p="/tmp/pipe$$"; mkfifo "$p"; (read na; cmd[s]...) <>"$p" & (echo;rm "$p"; cmd[s]...) >"$p"
Die
--index-file
Option von GNU tar funktioniert gut:quelle