STDOUTs vor STDERR anzeigen?

9

Ich bin neu im Bash und kann für mein ganzes Leben nicht herausfinden, wie man einen bestimmten Befehl ./fffausfü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
Miau
quelle
2
Hat cat"a" wirklich durch "some" ersetzt?
Dmitry Grigoryev
Oh verdammt, ich hätte die Saite durcheinander bringen können. Ich werde es sofort bearbeiten @DmitryGrigoryev
MeOw

Antworten:

18

Sie müssen die stderr-Ausgabe ohnehin irgendwo halten , um sie am Ende anzeigen zu können.

Eine Datei fällt mir ein:

fff 2> file; cat file >&2

Oder Speicher (hier mit spongevon moreutils):

{ fff 2>&1 >&3 3>&- | sponge >&2 3>&-; } 3>&1
  • {...} 3>&1: Innerhalb des {...}Dateideskriptors (fd) 3 zeigt auf dieselbe Ressource wie das ursprüngliche stdout (damit wir stdout für wiederherstellen können fff).
  • fff <redirs> | sponge <redirs>, fff Und spongegleichzeitig gestartet (mit <redirs>unabhängig angewandt) mit fff‚s stdout an ein Rohr geht, und sponge‘ s stdin das andere Ende des Rohres ist.
  • 2>&1: fd 2 von fff(stderr) zeigt auf dasselbe wie auf 1: die Pipe an dieser Stelle, also geht fffder Fehler spongeü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 was fffnicht benötigt
  • sponge 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 sie fffbeendet ist und bereits ihre gesamte Ausgabe in ihre Standardausgabe geschrieben hat).

Wenn spongenicht installiert, können Sie es durch ersetzen perl -0777 -pe ''. Mit -pe '', perlliest jeweils einen Datensatz von seiner Eingabe und schreibt ihn auf stdout. -0777ist der Slurp-Modus, in dem der (in diesem Fall nur einer) Datensatz die gesamte Eingabe ist.

Stéphane Chazelas
quelle
Bitte brechen Sie es auf, wenn Sie die Zeit haben!
George Udosen
Können wir teeanstelle von sponge... verwenden?
George Vasiliou
@ GeorgeUdosen siehe bearbeiten.
Stéphane Chazelas
1
@ GeorgeVasiliou, teeenthält keine Daten, schreibt sie, sobald sie gelesen werden.
Stéphane Chazelas
2
@MeOw: Das ist in Ordnung, aber wie die dritte Zeile von Stéphanes Antwort zeigt, müssen Sie den Standard nicht speichern. tu es einfach 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 sollten cat ferr.txt >&2, um die stderr-Informationen in den stderr zu schreiben .
G-Man sagt "Reinstate Monica"