Linux weniger Verhalten und stderr

11

Ich beobachte die Ausgabe meines komplizierten Befehls mit less, das Problem ist, dass das stderrverloren geht. stderrZeilen werden normalerweise zwischen den stdoutZeilen im Inneren aufgelistet less. Ich möchte, dass sie auf der Konsole gedruckt werden und beim Beenden lessgemeinsam dort angezeigt werden.

Ich weiß , es könnte keine Lösung für dieses Problem sein, las ich über teeund multiteeaber kein Glück so weit.

Haelix
quelle
2
Sie sagen mir, wie ich stderr zu stdout umleiten soll, aber das wollte ich nicht. Ich möchte nicht, dass sich stderr mit stdout in weniger vermischt. Ich möchte, dass stderr im Terminal ist, wenn ich weniger verlasse.
Wenn stderrumgeleitet wird stdout, alle Ausgaben an stderr werden auf den normalen Ausgang gemischt werden stdout. Wenn Sie diesen Ausgang an weiterleiten, lesswerden beide angezeigt .
Einige Programmierer Typ
Wenn ich "stderr, um im Terminal zu sein, wenn ich weniger beende" ignoriere, schlage ich vor, Strg-L zu drücken less, um den Bildschirm neu zu malen.
Kamae

Antworten:

10

Könnte sein

command 2> command.err | less; cat command.err; rm command.err

Nachtrag

Hier folgt eine Klarstellung für Leute, die es versäumen, die Frage sorgfältig zu lesen, und die den klarstellenden Kommentar des OP oben nicht gelesen haben.

Haelix wies darauf hin:

stderr-Zeilen werden normalerweise zwischen stdout-Zeilen in weniger aufgelistet

und schrieb in einem Kommentar für frühe Antwortende:

Sie sagen mir, wie ich stderr zu stdout umleiten soll, aber das wollte ich nicht. Ich möchte nicht, dass sich stderr mit stdout in weniger vermischt. Ich möchte, dass stderr im Terminal ist, wenn ich weniger verlasse

Das Problem ist wahrscheinlich plattformspezifisch, es ist sicherlich etwas, das ich auf älteren Unix SVR4-Plattformen erlebt habe.

Wenn Sie auf solchen Plattformen so etwas tun

 find / ... | less

Fehlermeldungen (z. B. Verzeichnisberechtigungen) werden in weniger Fällen so angezeigt

 stdout line 1
 stdout line 2
 error message text
 stdout line 4

so dass Ausgangsleitungen durch Fehlermeldungen verdeckt werden.

Wenn Sie die Seite aktualisieren, werden die Ausgabezeilen korrekt angezeigt, aber Sie verlieren die Fehlermeldungen. Wenn Sie weniger beenden, wird der Bildschirm bis auf eine Eingabeaufforderung gelöscht.

Wenn du so etwas machst

  find / ... 2>&1 | less

Die Fehlermeldungen werden mit der Standardausgabe vermischt. Wenn Sie weniger beenden, ist der Bildschirm wieder leer.

Wenn Sie zuerst nur die Standardausgabe in weniger lesen möchten und dann nach dem Beenden von weniger die Fehlermeldungen sehen möchten, benötigen Sie eine andere Lösung.

Das habe ich in meiner ursprünglichen zweizeiligen Antwort vorläufig vorgeschlagen.

RedGrittyBrick
quelle
Das ist Müll. Joachims Antwort sollte die akzeptierte sein.
Vanille Gesicht
2
@ VanillaFace: Ich habe meiner Antwort etwas Klärungsmaterial hinzugefügt.
RedGrittyBrick
15

Sie müssen umleiten stderrzu stdout:

$ ./somecommad 2>&1 | less

Überprüfen Sie das Handbuch für Ihre Shell (z man bash. B. )

Ein Programmierer
quelle
1
Kommentar für neue Leser dieser alten Frage (nicht besonders für Joachim) Dies ist, was jeder beim ersten Scannen der Frage denkt. Aber das Problem ist subtiler - siehe Diskussion in Kommentaren nach der Antwort von
dmckee
1

Sagen Sie der Shell einfach, dass sie fd 2 nach fd 1 umleiten soll (stderr nach stdout).

 make 2>&1 | less
Jackdoe
quelle
1

Eine Sache, die bisher in allen Antworten fehlte, ist der Grund, warum dies geschieht. Das Problem hierbei ist eine Art Race-Bedingung zwischen dem Prozess, der Daten an das Terminal ausgibt, stderrund der lessAnzeige der Ausgabe stdoutauf dem Terminal. Wenn lessdie Anzeige beginnt, nachdem alle Ausgaben an stderrdas Terminal gedruckt wurden, lesswird dies beibehalten, und Sie können die Meldungen nach dem Beenden sehen less. Wenn OTOH lessbereits mit der Anzeige von Inhalten begonnen hat, vermischen sich Fehlermeldungen mit lessder Ausgabe und nach dem Beenden bleibt nichts erhalten less(da lessdas Terminal nur so bleibt, wie es vor dem Start war, und nichts über die dazwischen liegenden Fehlermeldungen weiß).

Sie können das leicht sehen, wenn Sie z

grep foo -r /etc | less

Alle Fehlermeldungen "Berechtigung verweigert" werden mit der lessAusgabe verwechselt, und nach dem Beenden wird nichts mehr angezeigt. Wenn Sie tun

grep foo -r /etc | (sleep 10; less)

Alle (oder zumindest die meisten) Fehlermeldungen wurden auf dem Terminal gedruckt, bevor lessdie Ausgabe angezeigt werden kann. Anschließend werden die Fehlermeldungen angezeigt.

Natürlich möchten Sie normalerweise nicht 10 Sekunden warten, bevor Sie starten less, aber unter Linux können Sie auch Bruchwerte für die Wartezeit angeben, und bei schnell laufenden Prozessen reicht oft etwas sleep 0.1aus, um die Rennbedingungen zu vermeiden. (Aber natürlich, wenn Sie wollen oder müssen auf der seine wirklich sicheren Seite Einsatz RedGrittyBrick-Lösung).

Elmar Zander
quelle
0

Sie müssen das Konzept der "Dateideskriptoren" verstehen. Normalerweise startet eine Unix-Anwendung mit drei speziellen Dateideskriptoren:

  • Standardeingabe
  • Standardausgabe
  • Standart Fehler

Die "Pipe" |in der Shell verbindet sich stdoutvon einem Prozess mit stdindem nächsten.

Fehler werden vom Design her nicht in stdinden nächsten Prozess eingespeist . Sie sind für die nächste Anwendung oft nicht sinnvoll und sollten dem Benutzer nicht verborgen bleiben.

Wenn Sie die Fehler in stdout mischen möchten, können Sie z. B. 2>&1"stderr an stdout anhängen" verwenden. Zum Beispiel

find /etc 2>&1 | less

sollte auch Fehlerausgabe von unzugänglichen Dateien enthalten.

find /etc 2>&1 >/dev/null | less

gibt Ihnen nur die Fehler.

Hat aufgehört - Anony-Mousse
quelle
0

Ich bin verwirrt über Ihre Frage, soweit ich sagen kann, dass Ihr gewünschtes Verhalten die Standardeinstellung ist.

Wenn ich benutze

#include <stdio.h>

int main(int argc, char**argv){
  for (int j=0; j<10; ++j){
    fprintf( (j%2 ? stdout : stderr) , "%d\n" , j);
  }
  return 0;
}

um einen einfachen Test zu bekommen,

$ ./testredirection | less

macht genau das, was du fragst. Das sehe ich

1
3
5
7
9
(END) 

in lessund

$ ./testredirection | less
0
2
4
6
8
$ 

wenn ich aufhöre less

dmckee --- Ex-Moderator Kätzchen
quelle
Es ist seltsam, aber die Dinge sind nicht immer so. Versuchen Sie es mit einem Skript ( echo info ; echo error 1>&2) und wiederholen Sie den Test: Beide Zeilen werden auf weniger geleitet.
cYrus
@cYrus: Das funktioniert auch bei mir wie erwartet. Natürlich habe ich es mit einer Mac OS-Box versucht. Bash 3.2.17, weniger 394. Vielleicht etwas Linux-spezifisches. In jedem Fall sollte der Ansatz von RedGrittyBrick gut funktionieren.
dmckee --- Ex-Moderator Kätzchen
Seltsam! Debian Squeeze / Bash 4.1.5 / Less 436
cYrus
Ja, ich habe bei der Arbeit eine Shell der Scientific Linux 5.3-Box geöffnet und das erwartete Verhalten mit Bash 3.0.15 und weniger 382 erhalten. Könnte es dort eine Regression geben?
dmckee --- Ex-Moderator Kätzchen
Ich weiß nicht, ich denke, es ist nur eine Frage der Pufferung.
cYrus
0

Ich bin kürzlich in einem meiner Debian 5.0 auf dieses Problem gestoßen. Zum Beispiel ls abc | weniger finde ich, dass die Fehlermeldung in weniger geht, was gegen mein Wissen.

Nach einigen Versuchen stellte ich fest, dass es sich nur um Bildschirmpuffer handelt. stderr geht eigentlich NICHT auf weniger ein. Sie können die Aufwärts- oder Abwärtspfeiltasten (oder j / k) verwenden, um dies zu demonstrieren.

Beere
quelle