Ich bin neu im Bash und kann für mein ganzes Leben nicht herausfinden, wie man einen bestimmten Befehl ./fff
ausführt, reguläre Standard-Stdouts vor stderr annimmt und druckt (ich bin verwirrt über die Bedeutung selbst).
zum Beispiel
$ printf "I am a\ndrill\n" > fff;
$ cat fff nofile fff nofile fff
I am a
drill
cat: nofile: No such file or directory
I am a
drill
cat: nofile: No such file or directory
I am a
drill
muss drucken wie:
I am a
drill
I am a
drill
I am a
drill
cat: nofile: No such file or directory
cat: nofile: No such file or directory
Ich verstehe, dass ich meine Ausgabe zuerst in eine Datei umleiten und dann den Fehler an dieselbe Datei anhängen muss, aber dies ist die Ausgabe, für die ich erhalte
$ cat ./foo nofile ./foo nofile ./foo <<< $(touch fin) > see 2>> see
I am a
drill
I am a
drill
I am a
drill
ectory
cat: nofile: No such file or directory
cat
"a" wirklich durch "some" ersetzt?Antworten:
Sie müssen die stderr-Ausgabe ohnehin irgendwo halten , um sie am Ende anzeigen zu können.
Eine Datei fällt mir ein:
Oder Speicher (hier mit
sponge
vonmoreutils
):{...} 3>&1
: Innerhalb des{...}
Dateideskriptors (fd) 3 zeigt auf dieselbe Ressource wie das ursprüngliche stdout (damit wir stdout für wiederherstellen könnenfff
).fff <redirs> | sponge <redirs>
,fff
Undsponge
gleichzeitig gestartet (mit<redirs>
unabhängig angewandt) mitfff
‚s stdout an ein Rohr geht, undsponge
‘ s stdin das andere Ende des Rohres ist.2>&1
: fd 2 vonfff
(stderr) zeigt auf dasselbe wie auf 1: die Pipe an dieser Stelle, also gehtfff
der Fehlersponge
über diese Pipe weiter.>&3
: jetzt zeigt stdout auf das ursprüngliche stdout (leite zurück zu dem, was es war)3>&-
: wir schließen fd 2 wasfff
nicht benötigtsponge
sammelt seine Eingabe und zeigt sie nur an (auf dem Standard, mit dem umgeleitet wurde>&2
derselben Ressource wie stderr ), nachdem sie eof auf ihrer Standardausgabe erkannt hat (angenommen, wenn siefff
beendet ist und bereits ihre gesamte Ausgabe in ihre Standardausgabe geschrieben hat).Wenn
sponge
nicht installiert, können Sie es durch ersetzenperl -0777 -pe ''
. Mit-pe ''
,perl
liest jeweils einen Datensatz von seiner Eingabe und schreibt ihn auf stdout.-0777
ist der Slurp-Modus, in dem der (in diesem Fall nur einer) Datensatz die gesamte Eingabe ist.quelle
tee
anstelle vonsponge
... verwenden?tee
enthält keine Daten, schreibt sie, sobald sie gelesen werden.cat foo nofile foo nofile foo 2> ferr.txt; cat ferr.txt
. (Und Sie möchten es wahrscheinlich nicht verwenden>>
.) Außerdem macht Stéphane den hervorragenden Punkt, den Sie wahrscheinlich tun solltencat ferr.txt >&2
, um die stderr-Informationen in den stderr zu schreiben .