Frage bash: druck stderr in roter farbe


Gibt es eine Möglichkeit, Bash-Display zu machen? stderr Nachrichten in roter Farbe?


97
2017-08-26 21:10


Ursprung


Ich nehme an, dass bash seine Ausgabe niemals kolorieren wird: Einige Programme wollen etwas parsen, und das Kolorieren verfälscht Daten mit Escape-Sequenzen. Eine GUI-App sollte mit Farben umgehen, denke ich. - kolypto
Kombinieren Balázs Pozsár und killdash9 Antwort gibt das scharfe: function color { "$@" 2> >(sed $'s,.*,\e[31m&\e[m,') }  Funktioniert für Bash und Zsh. Kann das nicht als Antwort b / c-Reputation hinzufügen. - Heinrich Hartmann
Ich warte auf eine Antwort, die bash ändert, um dies zu tun. Die Lösungen unter allen tatsächlich Modifizieren Sie stderr und möglicherweise sogar neu ordnen Sie w.r.t. stdout, das Dinge unterbricht, wenn die exakte Byte-Sequenz von stderr beibehalten werden muss, z. wenn Rohrleitungen. - masterxilo


Antworten:


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

84
2017-08-26 21:39



Großartig! Aber ich frage mich, ob es einen Weg gibt, es dauerhaft zu machen :) - kolypto
Toller Tipp! Vorschlag: Durch Hinzufügen >&2 kurz bevor ; done)Die für stderr bestimmte Ausgabe wird tatsächlich in stderr geschrieben. Das ist hilfreich, wenn Sie die normale Ausgabe des Programms erfassen möchten. - henko
Die folgenden Anwendungen tputund ist meiner Meinung nach etwas besser lesbar: command 2> >(while read line; do echo -e "$(tput setaf 1)$line$(tput sgr0)" >&2; done) - Stefan Lasiewski
Ich denke, das Ausführen von 2 tput-Prozessen für jede Ausgangsleitung ist überhaupt nicht elegant. Vielleicht, wenn Sie die Ausgabe der tput-Befehle in einer Variablen speichern und diese für jedes Echo verwenden würden. Aber auch hier ist die Lesbarkeit nicht wirklich besser. - Balázs Pozsár
Diese Lösung behält keine Leerzeichen bei, aber ich mag sie für ihre Kürze. IFS= read -r line sollte helfen, tut es aber nicht. Nicht sicher warum. - Max Murphy


Methode 1: Verwenden Sie Prozesssubstitution:

command 2> >(sed $'s,.*,\e[31m&\e[m,'>&2)

Methode 2: Erstellen Sie eine Funktion in einem Bash-Skript:

color()(set -o pipefail;"$@" 2>&1>&3|sed $'s,.*,\e[31m&\e[m,'>&2)3>&1

Benutze es so:

$ color command

Beide Methoden zeigen die Befehle an stderr in rot.

Lesen Sie weiter, um zu erfahren, wie Methode 2 funktioniert. Dieser Befehl enthält einige interessante Funktionen.

  • color()... - Erstellt eine Bash-Funktion namens color.
  • set -o pipefail - Dies ist eine Shell-Option, die den Fehler-Return-Code eines Befehls beibehält, dessen Ausgabe an einen anderen Befehl weitergeleitet wird. Dies geschieht in einer Subshell, die durch die Klammern erzeugt wird, um die Pipefail-Option in der äußeren Shell nicht zu ändern.
  • "$@" - Führt die Argumente für die Funktion als neuen Befehl aus. "$@" ist äquivalent zu "$1" "$2" ...
  • 2>&1 - Weist die stderr des Befehls zu stdout so dass es wird sedist es stdin.
  • >&3 - Kurzschrift für 1>&3, das leitet weiter stdout zu einem neuen temporären Dateideskriptor 3. 3 wird zurückgeleitet in stdout später.
  • sed ... - Wegen der Weiterleitungen oben, sedist es stdin ist der stderr des ausgeführten Befehls. Seine Funktion besteht darin, jede Zeile mit Farbcodes zu umgeben.
  • $'...' Ein Bash-Konstrukt, durch das Zeichen mit Backslash-Escape erkannt werden
  • .* - Entspricht der gesamten Linie.
  • \e[31m - Die ANSI-Escape-Sequenz, die bewirkt, dass die folgenden Zeichen rot sind
  • & - Das sed Ersetzen Sie das Zeichen, das auf die gesamte übereinstimmende Zeichenfolge erweitert wird (in diesem Fall die gesamte Zeile).
  • \e[m - Die ANSI-Escape-Sequenz, die die Farbe zurücksetzt.
  • >&2 - Kurzschrift für 1>&2, das leitet weiter sedist es stdout zu stderr.
  • 3>&1 - Leitet den temporären Dateideskriptor um 3 zurück in stdout.

72
2018-04-23 20:53



+1 beste Antwort! absolut unterschätzt! - muhqu
Große Antwort und noch bessere Erklärung - Daniel Serodio
Warum müssen Sie alle zusätzlichen Umleitungen durchführen? scheint wie Overkill - qodeninja
@qodeninja Die Erklärung gibt den Zweck für die Umleitung. Wenn Sie einen einfacheren Weg finden können, würde ich es gerne sehen! - killdash9
Gibt es einen Weg, damit es funktioniert? zsh? - Eyal Levin


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


23
2017-12-13 21:40



Wow, dieses Dienstprogramm ist großartig, das einzige, was es brauchen würde, ist ein Apt-Repository, das es für alle Benutzer mit einer Zeile installiert, ohne weitere Arbeit zu machen, um es zu aktivieren. - sorin
Scheint gut zu funktionieren, wenn ich es mit einem Build - Skript in einem separaten Terminal getestet habe, aber ich zögere, es global zu benutzen (in .bashrc). Trotzdem danke! - Joel Purra
In OS X El Capitan ist die Funktionsweise (DYLD_INSERT_LIBRARIES) in Systembinärdateien "gebrochen", weil sie durch SIP geschützt sind. Daher ist es besser, die Bash-Optionen zu verwenden, die in anderen Antworten angegeben sind. - hmijail
@hmijail für MacOS bitte folgen github.com/sickill/stderred/issues/60 So können wir einen Workaround finden, ein Teil existiert bereits, ist aber ein wenig fehlerhaft. - sorin


http://sourceforge.net/projects/hilite/


14
2017-08-26 21:18





Die Bash Art zu machen stderr permanent rot verwendet 'exec', um Streams umzuleiten. Fügen Sie Ihrem bashrc folgendes hinzu:

exec 9>&2
exec 8> >(
    while IFS='' read -r line || [ -n "$line" ]; do
       echo -e "\033[31m${line}\033[0m"
    done
)
function undirect(){ exec 2>&9; }
function redirect(){ exec 2>&8; }
trap "redirect;" DEBUG
PROMPT_COMMAND='undirect;'

Ich habe dazu schon vorher gepostet: Wie man Schriftfarbe für STDOUT und STDERR einstellt


11
2018-01-29 08:49



verbunden: unix.stackexchange.com/questions/367636/ ... - Blauhirn
Dies ist die beste Antwort bei weitem; einfach zu implementieren ohne Installation / erfordern sudo Privilegien, und kann für alle Befehle verallgemeinert werden. - Luke Davis
Leider funktioniert das nicht gut mit der Befehlskette (Befehl && nextCommand || errorHandlerCommand). Die Ausgabe des Fehlers erfolgt nach der Ausgabe von errorHandlerCommand. - carlin.scott
Ähnlich, wenn ich source ~/.bashrc zweimal damit schließt mein Terminal grundsätzlich ab. - Dolph
@Dolf: In meinem bashrc behalte ich das leicht mit einer umgebenden if-Anweisung, um zu verhindern, dass dieser Code neu geladen wird. Ansonsten ist das Problem die Umleitung 'exec 9> & 2' nachdem die Umleitung bereits stattgefunden hat. Vielleicht ändern Sie es in eine Konstante, wenn Sie wissen, wo> 2 auf ursprünglich zeigt. - gospes


Ich habe ein Wrapper-Skript erstellt, das Balázs Pozsárs Antwort in purer Bash umsetzt. Speichern Sie es in Ihren $ PATH- und Präfix-Befehlen, um ihre Ausgabe zu kolorieren.


    #! / bin / bash

    if [$ 1 == "--help"]; dann
        echo "Führt einen Befehl aus und koloriert alle aufgetretenen Fehler"
        echo "Beispiel:` Basisname $ {0} `wget ..."
        echo "(c) o_O Tync, ICQ # 1227-700, Viel Spaß!"
        beenden Sie 0
        fi

    # Temp-Datei, um alle Fehler zu erfassen
    TMP_ERRS = $ (mktemp)

    # Befehl ausführen
    "$ @" 2>> (während Zeile lesen; echo -e "\ e [01; 31m $ Zeile \ e [0m" | tee --Zusatz $ TMP_ERRS; fertig)
    EXIT_CODE = $?

    # Zeigen Sie alle Fehler erneut an
    if [-s "$ TMP_ERRS"]; dann
        echo -e "\ n \ n \ n \ e [01; 31m === FEHLER === \ e [0m"
        Katze $ TMP_ERRS
        fi
    rm -f $ TMP_ERRS

    # Fertig
    Beenden Sie $ EXIT_CODE


7
2017-08-26 22:13



Dies könnte effizienter gemacht werden, wenn "| tee ..." nach "erledigt" gesetzt wird. - Juliano


Sie können eine Funktion wie diese verwenden


 #!/bin/sh

color() {
      printf '\033[%sm%s\033[m\n' "$@"
      # usage color "31;5" "string"
      # 0 default
      # 5 blink, 1 strong, 4 underlined
      # fg: 31 red,  32 green, 33 yellow, 34 blue, 35 purple, 36 cyan, 37 white
      # bg: 40 black, 41 red, 44 blue, 45 purple
      }
string="Hello world!"
color '31;1' "$string" >&2


3
2017-08-26 22:29



Das Problem nicht angehen. Sie haben keine Möglichkeit zur Verfügung gestellt, stderr von stdout zu trennen, woran der O.P interessiert ist. - Jeremy Visser


Ich habe eine leicht modifizierte Version von O_o Tync's Skript. Ich musste diese Mods für OS X Lion machen und es ist nicht perfekt, weil das Skript manchmal abgeschlossen wird, bevor der Wrapped-Befehl ausgeführt wird. Ich habe einen Schlaf hinzugefügt, aber ich bin mir sicher, dass es einen besseren Weg gibt.

#!/bin/bash

   if [ $1 == "--help" ] ; then
       echo "Executes a command and colorizes all errors occured"
       echo "Example: `basename ${0}` wget ..."
       echo "(c) o_O Tync, ICQ# 1227-700, Enjoy!"
       exit 0
       fi

   # Temp file to catch all errors
   TMP_ERRS=`mktemp /tmp/temperr.XXXXXX` || exit 1

   # Execute command
   "$@" 2> >(while read line; do echo -e "$(tput setaf 1)$line\n" | tee -a $TMP_ERRS; done)
   EXIT_CODE=$?

   sleep 1
   # Display all errors again
   if [ -s "$TMP_ERRS" ] ; then
       echo -e "\n\n\n$(tput setaf 1) === ERRORS === "
       cat $TMP_ERRS
   else
       echo "No errors collected in $TMP_ERRS"
   fi
   rm -f $TMP_ERRS

   # Finish
   exit $EXIT_CODE

1
2018-06-08 17:37