Gibt es in bash eine Möglichkeit, STDERR durch einen Filter zu leiten, bevor es mit STDOUT vereinheitlicht wird? Das heißt, ich will
STDOUT ────────────────┐
├─────> terminal/file/whatever
STDERR ── [ filter ] ──┘
eher, als
STDOUT ────┐
├────[ filter ]───> terminal/file/whatever
STDERR ────┘
Antworten:
Hier ist ein Beispiel, das dem Austausch von Dateideskriptoren in Bash nachempfunden ist . Die Ausgabe von a.out ist die folgende ohne das Präfix 'STDXXX:'.
STDERR: stderr output STDOUT: more regular ./a.out 3>&1 1>&2 2>&3 3>&- | sed 's/e/E/g' more regular stdErr output
Zitat aus dem obigen Link:
quelle
3>&2 2>&1 1>&3-
.Eine naive Verwendung der Prozesssubstitution scheint das Filtern von
stderr
getrennt von zu ermöglichenstdout
::; ( echo out ; echo err >&2 ) 2> >( sed s/^/e:/ >&2 ) out e:err
Beachten Sie, dass
stderr
auf herauskommtstderr
undstdout
aufstdout
, die wir durch das Einwickeln das Ganze in einem anderen Sub - Shell und Umleitung auf Dateien sehen könneno
unde
( ( echo out ; echo err >&2 ) 2> >( sed s/^/e:/ >&2 ) ) 1>o 2>e
quelle
$
als Eingabeaufforderung. Dann schreiben sie oft Shell-Beispiele wie :$ cat /var/log/syslog | fgrep ...
. Diese Zeile kann jedoch aufgrund der nicht kopiert werden$
.:;
sieht aus wie eine Eingabeaufforderung, ist aber im Grunde ein Shell-No-Op; So können Sie die gesamte Zeile sicher auswählen und einfügen.TL; DR:
Beispiel:
Dies funktioniert sowohl in bash als auch in zsh. Bash ist so ziemlich überall in diesen Tagen, aber wenn Sie wirklich eine (wirklich gnarly) Lösung für POSIX benötigen
sh
, dann hier sehen .Erläuterung
Der mit Abstand einfachste Weg, dies zu tun, besteht darin, STDERR über die Prozessersetzung umzuleiten :
Was Sie also mit der Prozesssubstitution erhalten, ist ein Dateiname.
Genau wie Sie es tun könnten:
du kannst tun
Der STDOUT der
>&2
Weiterleitungfilter
kehrt zum ursprünglichen STDERR zurück.quelle
exec 2> >(while .. read .. echo)
in einem Skript verbrannt, das als systemd-Dienst ausgeführt wird. journald erfasst fd2 des Dienstes und leitet die Protokollstufe von einem Präfix '<N>' ab: Vor<2>
den Ausgabezeilen voranstellen , und Sie erhalten die Fehlerstufe, die den Journaldatensätzen zugewiesen ist. Aber manchmal war systemd schneller, um die gesamte Prozessgruppe beim Beenden der Hauptgruppe zu beenden, bevor sie ihre letzte, wichtigste Nachricht protokollieren konnte!TL; DR: (bash und zsh)
Beispiel:
Viele Antworten im StackExchange-Netzwerk haben die Form:
cat /non-existant 3>&1 1>&2 2>&3 3>&- | sed 's/e/E/g'
Dies hat eine eingebaute Annahme: Der Dateideskriptor 3 wird nicht für etwas anderes verwendet.
Verwenden Sie stattdessen einen benannten Dateideskriptor und
{ba,z}sh
weisen Sie den nächsten verfügbaren Dateideskriptor> = 10 zu:cat /non-existant {tmp}>&1 1>&2 2>&$tmp {tmp}>&- | sed 's/e/E/g'
Beachten Sie, dass benannte Dateideskriptoren von POSIX nicht unterstützt werden
sh
.Das andere Problem mit dem oben Gesagten ist, dass der Befehl nicht an weitere Befehle weitergeleitet werden kann, ohne STDOUT und STDERR wieder auf ihre ursprünglichen Werte zurückzusetzen.
Um eine Weiterleitung in POSIX zu ermöglichen
sh
(und immer noch davon auszugehen, dass FD 3 nicht verwendet wird), wird es kompliziert :Angesichts der Annahme und der knorrigen Syntax ist es wahrscheinlich besser, die einfachere
bash
/zsh
Syntax zu verwenden, die in der obigen TL; DR gezeigt und hier erläutert wird .quelle
Ich finde die Verwendung der Bash-Prozess-Substitution leichter zu merken und zu verwenden, da sie die ursprüngliche Absicht fast wörtlich widerspiegelt. Zum Beispiel:
$ cat ./p echo stdout echo stderr >&2 $ ./p 2> >(sed -e 's/s/S/') | sed 's/t/T/' sTdout STderr
Verwendet den ersten sed-Befehl nur als Filter für stderr und den zweiten sed-Befehl, um die verknüpfte Ausgabe zu ändern.
Beachten Sie, dass der Leerraum nach 2> obligatorisch ist, damit der Befehl korrekt analysiert werden kann.
quelle
Der letzte Teil dieser Seite des Advanced Bash Scripting Guide ist "Nur stderr in eine Pipe umleiten".
Dies kann sein, was Sie wollen. Wenn nicht, sollte Ihnen ein anderer Teil des ABSG helfen können, es ist ausgezeichnet.
quelle
Schauen Sie sich die genannten Rohre an:
quelle
cat - err
die Streuung von stdout und stderr brechen?