Sagen Sie sofort, welche Ausgabe an stderr gesendet wurde

8

Wenn Sie eine Aufgabe automatisieren, ist es sinnvoll, sie zuerst manuell zu testen. Es wäre jedoch hilfreich, wenn Daten, die an stderr gesendet werden, sofort als solche erkennbar und von den Daten, die an stdout gesendet werden, unterscheidbar wären, und alle Ausgaben zusammen zu haben, damit die Reihenfolge der Ereignisse offensichtlich ist.

Eine letzte Berührung, die schön wäre, wäre, wenn beim Beenden des Programms der Rückkehrcode gedruckt würde.

All diese Dinge würden bei der Automatisierung helfen. Ja, ich kann den Rückkehrcode wiederholen, wenn ein Programm beendet ist, und ja, ich kann stdout und stderr umleiten. Was ich wirklich mag, ist eine Shell, ein Skript oder ein benutzerfreundlicher Redirector, der stdout in Schwarz anzeigt, stderr in Rot verschachtelt zeigt und den Exit-Code am Ende druckt.

Gibt es so ein Biest? [Wenn es darauf ankommt, verwende ich Bash 3.2 unter Mac OS X].


Update : Es ist leider Monate her, seit ich mir das angeschaut habe. Ich habe mir ein einfaches Testskript ausgedacht:

#!/usr/bin/env python
import sys

print "this is stdout"
print >> sys.stderr, "this is stderr"
print "this is stdout again"

In meinen Tests (und wahrscheinlich aufgrund der Art und Weise, wie die Dinge gepuffert sind) zeigen rse und hilite alles von stdout und dann alles von stderr an. Die fifo-Methode stimmt die Reihenfolge, scheint aber alles zu färben, was der stderr-Linie folgt. ind beschwerte sich über meine stdin und stderr Zeilen und setzte dann die Ausgabe von stderr zuletzt.

Die meisten dieser Lösungen sind funktionsfähig, da es nicht untypisch ist, dass nur die letzte Ausgabe an stderr gesendet wird. Trotzdem wäre es schön, etwas zu haben, das etwas besser funktioniert.

Clinton Blackmore
quelle
Wenn Sie faul sind (oder schmerzende Finger haben) wie ich, können Sie eine Unterschale mit den folgenden Lösungen (z. B. rse zsh) greifen und jetzt färben alle Befehle stderr.
Voreingenommenheit

Antworten:

3

Sie können auch stderred auschecken: https://github.com/sickill/stderred

sickill
quelle
Leider bricht stderred für Mac-Benutzer wie das OP "open" und "mvim".
AlcubierreDrive
Dies funktioniert sehr gut und erhält die Ausgabereihenfolge aufgrund der Funktionsweise in der richtigen Weise. Richten Sie es einmal ein und aktivieren Sie es in Ihrem Profil. Sie erhalten rote Nachrichten, wenn auf stderr geschrieben wird.
Clinton Blackmore
1
@ JonRodriguez, es scheint mir, dass das Problem mit dem Befehl "Öffnen" behoben wurde .
Clinton Blackmore
9

Ich habe gerade eine verrückte Methode mit FIFOs entwickelt.

$ mkfifo foo
$ grep --color . foo &
$ your_command 2>foo

Wenn Sie möchten, dass die stderr-Ausgabe separat ausgeführt wird, können Sie zwei separate Shells öffnen und " grep --color . foo" in einer ohne die &ausführen und dann den Befehl in der anderen ausführen (immer noch mit der 2>foo). Sie erhalten den stderr im grepeinen und den stdout im wichtigsten.

Dies funktioniert, weil die stderr-Ausgabe über das FIFO in geleitet wird grep --color, dessen Standardfarbe Rot ist (zumindest für mich). Wenn Sie fertig sind, nur rmdas FIFO ( rm foo).

Vorsichtsmaßnahme : Ich bin mir wirklich nicht sicher, wie dies mit der Ausgabereihenfolge umgehen soll. Sie müssen es testen.

jtbandes
quelle
Das ist ziemlich schlau.
Clinton Blackmore
7

Ja, das ist möglich. Ein funktionierendes Beispiel finden Sie im Abschnitt "STDERR rot machen" auf dieser Site .

Der Grundcode ist dieser

# Red STDERR
# rse <command string>
function rse()
{
    # We need to wrap each phrase of the command in quotes to preserve arguments that contain whitespace
    # Execute the command, swap STDOUT and STDERR, colour STDOUT, swap back
    ((eval $(for phrase in "$@"; do echo -n "'$phrase' "; done)) 3>&1 1>&2 2>&3 | sed -e "s/^\(.*\)$/$(echo -en \\033)[31;1m\1$(echo -en \\033)[0m/") 3>&1 1>&2 2>&3
}

Eine kurze Erklärung finden Sie in der Funktion selbst. Was bewegt wird, ist STDOUT und STDERR zu bewegen, also erhält sed STDERR in 1, färbt es und tauscht es dann zurück. Stellen Sie sich File Stream 3 hier als temporäre Variable vor.

Der Anruf ist ziemlich einfach

rse commands

Bestimmte Aufrufe funktionieren jedoch nicht wie erwartet. Die Vorbehalte finden Sie alle auf der verlinkten Seite.

Übrigens denke ich, dass es auch möglich ist, eine Lösung der Form zu finden

commands | rse 

Dabei färbt rse die Ausgabe ein.

Ich fand auch dieses hilite Projekt , das dies zu tun scheint. Ich habe es nicht ausprobiert, aber es könnte das sein, wonach Sie suchen.

hilite ist ein winziges Dienstprogramm, das den von Ihnen angegebenen Befehl ausführt und alles hervorhebt, was auf stderr gedruckt wurde. Es wurde hauptsächlich für die Verwendung mit Builds entwickelt, damit Warnungen und Fehler wie ein schmerzendes Klischee hervorstechen.

Andere verwandte Projekte:


quelle
rse und hilite sind ziemlich nah an dem, was ich will.
Clinton Blackmore
1

Ein anderes Programm ist ind:

http: // www.habets.pp.se/synscan/programs.php?prog=ind (Sie müssen den Hyperlink selbst zusammenstellen, ich habe nicht genug Punkte für mehr als einen pro Antwort). Dort gibt es einen Screenshot und sogar einen Screencast.

Es führt den Unterprozess in einem Pty aus, was die anderen wahrscheinlich nicht tun. Dies kann wichtig sein, wo die Reihenfolge wichtig ist (was häufig der Fall ist), da stderr sofort in Terminals gespült wird und stdout vollständig gepuffert wird, wenn es kein tty ist.

Eine vollständige Erklärung finden Sie hier: http://blog.habets.pp.se/2008/06/Buffering-in-pipes

Ind arbeitet auch mit interaktiven Programmen und Steuerzeichen. Bash funktioniert wie gewohnt, wenn mit "ind bash -i" begonnen wird.

Dies könnte funktionieren, um Ihnen Farben zu geben, während Strg-P ​​et al.

ind -P $(echo -ne '\033[31;1m') -p $(echo -ne '\033[0m') bash -i
Thomas
quelle
1

Hier finden Sie viele Antworten zum Hervorheben der stderr-Ausgabe. Ich kann nur eine ziemlich einfache hinzufügen - in einer Zeile, die Sie dem Befehl hinzufügen:

command 2> >(while read line; do echo -e "\e[01;31m$line\e[0m"; done)

Sie müssen dies jedoch jedes Mal nach dem Befehl hinzufügen.

Ich persönlich mag die von @nagul erwähnte Möglichkeit, die rse-Funktion zu bashrc hinzuzufügen.

Aber ich möchte die Lösung zum Drucken des Exit-Codes hinzufügen. Sie können diesen Wert am Anfang Ihrer Bash-Eingabeaufforderungszeile hinzufügen:

hostname$ command
  Some error occurred. Returned exit code.
EC hostname$

Wobei EC der Exit-Code des Befehls ist.

Ich habe es so eingestellt, dass wenn der Exit-Code 0 ist, er nicht gedruckt wird, aber jeder andere Wert vor der nächsten Eingabeaufforderung in roter Farbe gedruckt wird.

Der ganze Trick wird in ~ / .bashrc gemacht:

my_prompt() {
 EXITSTATUS="$?"
 RED="\[\033[1;31m\]"
 OFF="\[\033[m\]"

PROMPT="${debian_chroot:+($debian_chroot)}\h \$ "

if [ "${EXITSTATUS}" -eq 0 ]; then
   PS1="${PROMPT}"
else
   PS1="${RED}$EXITSTATUS${OFF} ${PROMPT}"
fi
}

PROMPT_COMMAND=my_prompt

Die Eingabeaufforderungszeile wird standardmäßig durch die Variable PS1 definiert. Kopiere alles, was du hier hast, in die Variable PROMPT und erstelle dann die PS1-Variable mit oder ohne Exit-Code.

Bash zeigt die Informationen in der PS1-Variablen in der Eingabeaufforderung an.

srnka
quelle
Genau das habe ich gesucht, danke!
Dylon
1

Es gibt ein annotate-outputDienstprogramm ( devscriptsDebian-Paket), wenn Sie es ohne Farben tun möchten

$ annotate-output /tmp/test.py    
14:24:57 I: Started /tmp/test.py
14:24:57 E: this is stderr
14:24:57 O: this is stdout
14:24:57 O: this is stdout again
14:24:57 I: Finished with exitcode 0
Mykhal
quelle