Ich möchte mein Terminal so einrichten, dass stderr
es in einer anderen Farbe gedruckt wird als stdout
; vielleicht rot. Dies würde es einfacher machen, die beiden voneinander zu unterscheiden.
Gibt es eine Möglichkeit, dies zu konfigurieren .bashrc
? Wenn nicht, ist das überhaupt möglich?
Hinweis : Diese Frage wurde mit einer anderen Frage zusammengeführt stderr
, stdout
und das Benutzereingabe-Echo wurde in 3 verschiedenen Farben ausgegeben . Die Antworten können sich auf beide Fragen beziehen.
Antworten:
Dies ist eine härtere Version von Show only stderr on screen, aber schreibe sowohl stdout als auch stderr in die Datei .
Die auf dem Terminal ausgeführten Anwendungen verwenden einen einzelnen Kanal, um mit ihm zu kommunizieren. Die Anwendungen haben zwei Ausgangsports, stdout und stderr, aber beide sind mit demselben Kanal verbunden.
Sie können einen davon mit einem anderen Kanal verbinden, diesem Kanal Farbe hinzufügen und die beiden Kanäle zusammenführen. Dies führt jedoch zu zwei Problemen:
␛[31m
"auf roten Vordergrund umschalten". Dies bedeutet, dass die Ausgabe verfärbt wird, wenn eine Ausgabe für stdout eingeht, während eine Ausgabe für stderr angezeigt wird. (Schlimmer noch, wenn sich mitten in einer Escape-Sequenz ein Kanalwechsel befindet, sehen Sie Müll.)Im Prinzip wäre es möglich, ein Programm zu schreiben, das synchron auf zwei ptys¹ lauscht (dh Eingaben auf einem Kanal werden nicht akzeptiert, während Ausgaben auf dem anderen Kanal verarbeitet werden) und sofort mit entsprechenden Anweisungen zum Farbwechsel an das Terminal auszugeben. Sie verlieren die Möglichkeit, Programme auszuführen, die mit dem Terminal interagieren. Ich kenne keine Implementierung dieser Methode.
Ein anderer möglicher Ansatz wäre, das Programm zu veranlassen, die richtigen Farbänderungssequenzen auszugeben, indem alle libc-Funktionen, die den
write
Systemaufruf aufrufen, in einer mit geladenen Bibliothek eingebunden werdenLD_PRELOAD
. Sehen Sie sich die Antwort von sickill für eine vorhandene Implementierung oder die Antwort von Stéphane Chazelas für einen gemischten Ansatz an, der die Vorteile nutztstrace
.In der Praxis empfehle ich, wenn dies zutrifft, stderr auf stdout umzuleiten und in einen musterbasierten Colorizer wie Colortail oder Multitail oder spezielle Colorizer wie Colorgcc oder Colormake zu leiten .
¹ Pseudo-Terminals. Pipes würden aufgrund von Pufferung nicht funktionieren: Die Quelle könnte in den Puffer schreiben, was die Synchronität mit dem Colorizer beeinträchtigen würde.
quelle
LD_PRELOAD
Tricks zum Abfangen vonwrite
Anrufen scheint am besten geeignet zu sein, IMO (aber es kann auch Unterschiede bei bestimmten * nix-Varianten geben.)write
würde das Abfangen alleine nicht funktionieren, da die meisten Anwendungen nicht direkt aufrufen, sondern eine andere Funktion aus einer gemeinsam genutzten Bibliothek (wieprintf
), die das Original aufrufen würdewrite
write
Syscall-Wrapper zu kümmern . Ist es in anderen Funktionen in Glibc eingebettet?write
via zu sein,LD_PRELOAD
wie Sie beschreiben.Auschecken
stderred
. Es verwendet ,LD_PRELOAD
um hooklibc
‚swrite()
Anrufe Einfärben allestderr
Ausgänge gehen an einen Terminal. (Standardmäßig in Rot.)quelle
Das Färben von Benutzereingaben ist schwierig, da sie in der Hälfte der Fälle vom Terminaltreiber (mit lokalem Echo) ausgegeben werden. In diesem Fall weiß möglicherweise keine Anwendung, die in diesem Terminal ausgeführt wird, wann der Benutzer Text eingeben und die Ausgabefarbe entsprechend ändern wird . Nur der Pseudo-Terminal-Treiber (im Kernel) weiß, dass der Terminal-Emulator (wie xterm) bei einem Tastendruck einige Zeichen sendet, und der Terminal-Treiber sendet möglicherweise einige Zeichen für das Echo zurück, aber xterm kann nicht wissen, ob diese vom stammen lokales Echo oder was die Anwendung an die Slave-Seite des Pseudoterminals ausgibt).
Und dann gibt es noch den anderen Modus, in dem der Terminal-Treiber angewiesen wird, nicht zu echo, sondern die Anwendung diesmal etwas ausgibt. Die Anwendung (wie die, die readline wie gdb, bash ... verwenden) sendet möglicherweise das auf stdout oder stderr, was schwierig von etwas zu unterscheiden ist, das sie für andere Zwecke ausgibt, als die Benutzereingabe zurückzugeben.
Es gibt verschiedene Ansätze, um den Standardwert einer Anwendung von ihrem Standardwert zu unterscheiden.
Bei vielen von ihnen werden die Befehle stdout und stderr an Pipes umgeleitet, und diese Pipes werden von einer Anwendung gelesen, um sie einzufärben. Damit sind zwei Probleme verbunden:
Ein weiterer Ansatz besteht darin, die Anwendung so zu ändern, dass sie ihre Standard- und Standardfarben einfärbt. Dies ist oft nicht möglich oder realistisch.
Dann kann ein Trick (für dynamisch verknüpfte Anwendungen) darin bestehen, die von der Anwendung aufgerufenen Ausgabefunktionen zu missbrauchen (
$LD_PRELOAD
wie in der Antwort von sickill ), um etwas auszugeben, und darin Code aufzunehmen, der die Vordergrundfarbe basierend darauf festlegt, ob sie etwas ausgeben sollen auf stderr oder stdout. Dies bedeutet jedoch, dass jede mögliche Funktion aus der C-Bibliothek und jeder anderen Bibliothek entführt wird, die einenwrite(2)
Systemaufruf ausführt, der direkt von der Anwendung aufgerufen wird und möglicherweise etwas auf stdout oder stderr (printf, puts, perror ...) schreibt, und sogar dann kann sein Verhalten ändern.Ein anderer Ansatz könnte darin bestehen, PTRACE-Tricks bei jedem Aufruf des Systemaufrufs zu verwenden
strace
odergdb
sich selbst zu verbindenwrite(2)
und die Ausgabefarbe basierend darauf festzulegen, ob sich derwrite(2)
in Dateideskriptor 1 oder 2 befindet.Das ist jedoch eine ziemlich große Sache.
Ein Trick, mit dem ich gerade gespielt habe, ist,
strace
sich mit LD_PRELOAD selbst zu hijacken (was die Drecksarbeit macht, sich vor jedem Systemaufruf einzuhängen), um ihm mitzuteilen, dass er die Ausgabefarbe ändern soll, je nachdem, ob erwrite(2)
auf fd 1 oder a erkannt hat 2.Wenn
strace
wir uns den Quellcode ansehen, können wir sehen, dass alles, was er ausgibt, über dievfprintf
Funktion erfolgt. Alles was wir tun müssen, ist diese Funktion zu hijacken.Der LD_PRELOAD-Wrapper würde folgendermaßen aussehen:
Dann kompilieren wir es mit:
Und benutze es als:
Sie werden feststellen, dass beim Ersetzen
some-cmd
durchbash
die Bash-Eingabeaufforderung und diezsh
Eingabe in Rot (stderr) angezeigt wird, während sie in Schwarz angezeigt wird (da zsh stderr auf einen neuen fd kopiert, um die Eingabeaufforderung und das Echo anzuzeigen).Es scheint überraschend gut zu funktionieren, auch für Anwendungen, die Sie nicht erwarten würden (wie diejenigen, die Farben verwenden).
Der Farbmodus wird auf
strace
dem stderr ausgegeben , der als Terminal angenommen wird. Wenn die Anwendung ihre stdout oder stderr umleitet, schreibt unsere entführte Strace die farbigen Escape-Sequenzen weiterhin auf das Terminal.Diese Lösung hat ihre Grenzen:
strace
: Leistungsproblemen, Sie können keine anderen PTRACE-Befehle wiestrace
odergdb
darin oder Setuid / Setgid-Probleme ausführenwrite
Standard- / Standardfarben jedes einzelnen Prozesses. So zum Beispiel insh -c 'echo error >&2'
,error
wäre grün , weilecho
gibt sie auf seine stdout (die sh des stderr umgeleitet sh, aber alle Strace sieht einwrite(1, "error\n", 6)
). Und insh -c 'seq 1000000 | wc'
,seq
hat viel oder wenigwrite
mit seiner Standardausgabe zu tun, sodass der Wrapper am Ende viele (unsichtbare) Escape-Sequenzen auf dem Terminal ausgibt.quelle
strace $CMD | vim -c ':set syntax=strace' -
.Hier ist ein Proof of Concept, den ich vor einiger Zeit gemacht habe.
Es funktioniert nur in zsh.
Es wird auch davon ausgegangen, dass Sie eine Funktion namens setcolor haben.
Eine vereinfachte Version:
quelle
exec 2> >(rederr)
. In beiden Versionen wird es Probleme geben, die ich in meiner Antwort erwähne, nämlich die Reihenfolge der Zeilen zu ändern und die Ausgabe zu gefährden (insbesondere bei langen Zeilen).seterr
müsste ein eigenständiges Skript sein, keine Funktion.Siehe Mike Schiraldis Hilite, der dies jeweils für einen Befehl ausführt . Mein eigener Schwall tut dies für eine ganze Sitzung, hat aber auch viele andere Funktionen / Eigenheiten, die Sie vielleicht nicht wollen.
quelle
Einige frühere Diskussionen zu Serverfehlern.
Siehe auch grc und einen hilfreichen Blog dazu.
quelle