Linux weniger Verhalten und stderr

3801
haelix

Ich schaue mir die Ausgabe meines komplizierten Befehls an less, Problem ist das stderrgeht verloren. stderrZeilen werden normalerweise zwischen stdoutZeilen innerhalb aufgelistet less. Ich möchte, dass sie auf der Konsole gedruckt werden, und wenn ich das Fenster verlasse less, um sie dort zusammen zu sehen.

Mir ist klar, dass es dafür keine Lösung gibt, ich habe darüber gelesen teeund bisher multiteekein Glück.

8
Sie sagen mir, wie man stderr auf stdout umleitet, aber das wollte ich nicht. Ich möchte nicht, dass sich stderr mit stdout in weniger mischt. Ich möchte, dass stderr im Terminal ist, wenn ich weniger verlasse. vor 12 Jahren 1
Wenn "stderr" zu "stdout" umgeleitet wird, werden alle Ausgaben an "stderr" _will_ mit der normalen Ausgabe von "stdout" gemischt. Wenn Sie diese Ausgabe an "less" weiterleiten, werden beide angezeigt. Some programmer dude vor 12 Jahren 0
Wenn ich ignoriere, dass "stderr sich beim Beenden weniger im Terminal befindet", schlage ich vor, Strg-L in "less" zu drücken, um den Bildschirm neu zu zeichnen. kamae vor 12 Jahren 0

7 Antworten auf die Frage

14
Some programmer dude

Sie müssen weiterleiten stderran stdout:

$ ./somecommad 2>&1 | less 

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

Kommentar für neue Leser dieser alten Frage (nicht besonders für Joachim) Dies ist, was jeder beim ersten Scan der Frage denkt. Das Problem ist jedoch subtiler - siehe Diskussion in Kommentaren nach [Antwort von dmckee] (http://superuser.com/a/366615/52492) RedGrittyBrick vor 7 Jahren 1
7
RedGrittyBrick

Könnte sein

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

Nachtrag

Hier folgt eine Klarstellung für Leute, die die Frage nicht sorgfältig lesen und die oben erläuternden Erläuterungen des OP nicht gelesen haben.

haelix wies darauf hin:

stderr-Zeilen werden normalerweise zwischen stdout-Zeilen innerhalb von less aufgelistet

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

Sie sagen mir, wie man stderr auf stdout umleitet, aber das wollte ich nicht. Ich möchte nicht, dass sich stderr mit stdout in weniger mischt. 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 

etwaige Fehlermeldungen (z. B. Verzeichnisberechtigungen) werden in weniger so angezeigt

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

So werden die Ausgabezeilen durch Fehlermeldungen verdeckt.

Wenn Sie die Seite aktualisieren, werden die Ausgabezeilen korrekt angezeigt, die Fehlermeldungen gehen jedoch verloren. Wenn Sie weniger beenden, wird der Bildschirm mit Ausnahme einer Eingabeaufforderung gelöscht.

Wenn du sowas machst

 find / ... 2>&1 | less 

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

Wenn Sie zunächst nur die Standardausgabe in weniger anzeigen möchten und nach dem Beenden der Fehlermeldung die Fehlermeldungen sehen, benötigen Sie eine andere Lösung.

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

Das ist Müll. Die Antwort von Joachim sollte die akzeptierte sein. Vanilla Face vor 7 Jahren 0
@ VanillaFace: Ich habe meiner Antwort etwas klärendes Material hinzugefügt. RedGrittyBrick vor 7 Jahren 0
1
jackdoe

just tell the shell to redirect fd 2 to fd 1 (stderr to stdout)

 make 2>&1 | less 
1
Elmar Zander

Was bei allen Antworten bisher fehlte, ist der Grund, warum dies geschieht. Das Problem hier ist eine Art Race-Bedingung zwischen dem Prozess, der Sachen an das Terminal ausgibt stderrund lessdie Ausgabe davon anzeigt stdout. Wenn lessangezeigt wird, 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 dem Anzeigen von Daten begonnen hat, vermischen sich die Fehlermeldungen mit lessder Ausgabe und nichts bleibt nach dem Beenden erhalten less(da lessdas Terminal nur so bleibt, wie es war, bevor es gestartet wurde, und nichts über die dazwischen liegenden Fehlermeldungen weiß).

Sie können das leicht sehen, wenn Sie z

grep foo -r /etc | less 

Alle Fehlermeldungen "Permission denied" mischen sich mit der lessAusgabe, und nach dem Beenden ist nichts mehr vorhanden. Wenn Sie tun

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

Alle (oder zumindest die meisten) Fehlermeldungen wurden an das Terminal lessausgegeben, bevor die Ausgabe angezeigt werden kann. Anschließend werden die Fehlermeldungen angezeigt.

Natürlich möchten Sie normalerweise nicht 10 Sekunden vor dem Start warten less, aber mit Linux können Sie auch Bruchwerte für die Wartezeit angeben. Bei schnell ablaufenden Prozessen reicht oft etwas sleep 0.1aus, um die Race-Bedingung zu umgehen. (Aber wenn Sie auf der wirklich sicheren Seite sein wollen oder müssen, verwenden Sie die Lösung von RedGrittyBrick.)

0
Anony-Mousse

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

  • Standardeingabe
  • Standardausgabe
  • Standart Fehler

Das "Rohr" |in der Schale verbindet sich stdoutvon einem Prozess mit stdindem nächsten.

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

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

find /etc 2>&1 | less 

sollte auch Fehlerausgabe von nicht zugänglichen Dateien enthalten.

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

gibt Ihnen nur die Fehler.

0
dmckee

I'm confused about your question, as far as I ca tell your desired behavior is the default.

When I use

#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; } 

to get a simple test,

$ ./testredirection | less 

does just what you ask. That is I see

1 3 5 7 9 (END) 

in less and

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

when I quit less

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 zu weniger weitergeleitet. cYrus vor 12 Jahren 0
@cYrus: Das funktioniert auch für mich wie erwartet. „Natürlich habe ich es mit einer Mac OS Box probiert. Bash 3.2.17, weniger 394. Vielleicht etwas Linux-spezifisches. In jedem Fall sollte der Ansatz von RedGrittyBrick gut funktionieren. dmckee vor 12 Jahren 0
Seltsam! Debian Squeeze / Bash 4.1.5 / Less 436 cYrus vor 12 Jahren 0
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 da einen Rückschritt geben? dmckee vor 12 Jahren 0
Ich weiß nicht, ich denke, es ist nur eine Sache des Pufferns. cYrus vor 12 Jahren 0
@ cYrus: Mir fällt ein, dass der Unterschied wahrscheinlich das * Terminal * ist, das wir verwenden, da beide meine Tests in `xterm`s (Version 269) vom XQuartz 2.6.3 waren. In der Tat wird es bei Mac OS 10.5 "Terminal.app" beim ersten Mal "falsch" und anschließend "richtig". Huh Ich denke, das spricht für eine puffernde Erklärung, aber ich werde nicht mehr versuchen, es herauszufinden. dmckee vor 12 Jahren 0
Das Standardverhalten, das ich bekomme (ohne Umleitung) ist, dass stderr-Zeilen in weniger, aber auf flüchtige Weise ausgegeben werden: Wenn Sie sie aus dem Blickfeld rollen und zurückgehen, sind sie nicht da (auch nicht in der Konsole danach) weniger Ausgänge). haelix vor 12 Jahren 0
0
Berry

Dieses Problem ist kürzlich in einem meiner Debian 5.0 aufgetreten. zum Beispiel ls abc | Weniger finde ich, dass die Fehlermeldung in weniger geht, was gegen mein Wissen verstößt.

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