Question bash: impression stderr en couleur rouge


Est-il possible d'afficher bash stderr messages en couleur rouge?


97
2017-08-26 21:10


origine


J'imagine que bash ne colorera jamais sa sortie: certains programmes voudront peut-être analyser quelque chose, et la colorisation gâchera les données avec des séquences échappées. Une application graphique devrait gérer les couleurs, je suppose. - kolypto
La combinaison de Balázs Pozsár et de killdash9 donne la bonne réponse: function color { "$@" 2> >(sed $'s,.*,\e[31m&\e[m,') }  Fonctionne pour bash et zsh. Je ne peux pas ajouter ceci comme une réponse b / c. - Heinrich Hartmann
J'attends une réponse qui modifie bash pour le faire. Les solutions ci-dessous tout réellement modifier stderr et éventuellement même le réorganiser. stdout qui casse des choses lorsque la séquence d'octets exacte de stderr doit être préservée, par ex. lors de la tuyauterie. - masterxilo


Réponses:


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

84
2017-08-26 21:39



Génial! Mais je me demande s’il existe un moyen de le rendre permanent :) - kolypto
Bon conseil! Suggestion: En ajoutant >&2 juste avant ; done), la sortie destinée à stderr est en fait écrite dans stderr. Cela est utile si vous souhaitez capturer la sortie normale du programme. - henko
Les utilisations suivantes tput, et est un peu plus lisible à mon avis: command 2> >(while read line; do echo -e "$(tput setaf 1)$line$(tput sgr0)" >&2; done) - Stefan Lasiewski
Je pense que l'exécution de 2 processus de tput pour chaque ligne de sortie n'est pas élégante du tout. Peut-être que vous voudriez stocker le résultat des commandes tput dans une variable et utiliser celles-ci pour chaque écho. Mais là encore, la lisibilité n'est pas vraiment meilleure. - Balázs Pozsár
Cette solution ne préserve pas les espaces mais je l’aime pour sa brièveté. IFS= read -r line devrait aider mais ne le fait pas. Pas certain de pourquoi. - Max Murphy


Méthode 1: Utiliser la substitution de processus:

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

Méthode 2: Créer une fonction dans un script bash:

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

Utilisez-le comme ceci:

$ color command

Les deux méthodes montreront la commande stderr en rouge.

Continuez votre lecture pour une explication du fonctionnement de la méthode 2. Certaines fonctions intéressantes sont illustrées par cette commande.

  • color()... - Crée une fonction bash appelée couleur.
  • set -o pipefail - Il s'agit d'une option de shell qui conserve le code de retour d'erreur d'une commande dont la sortie est canalisée vers une autre commande. Ceci est fait dans un sous-shell, qui est créé par les parenthèses, afin de ne pas changer l'option pipefail dans le shell externe.
  • "$@" - Exécute les arguments de la fonction en tant que nouvelle commande. "$@" est équivalent à "$1" "$2" ...
  • 2>&1 - Redirige le stderr de la commande à stdout pour qu'il devienne sedde stdin.
  • >&3 - Sténographie pour 1>&3, cela redirige stdout vers un nouveau descripteur de fichier temporaire 3. 3 est renvoyé dans stdout plus tard.
  • sed ... - En raison des redirections ci-dessus, sedde stdin est le stderr de la commande exécutée. Sa fonction est d’entourer chaque ligne de codes de couleur.
  • $'...' Une construction bash qui lui permet de comprendre les caractères échappés par une barre oblique inversée
  • .* - Correspond à la ligne entière.
  • \e[31m - La séquence d'échappement ANSI qui fait que les caractères suivants sont rouges
  • & - Le sed remplace le caractère qui s'étend à la chaîne correspondante (la ligne entière dans ce cas).
  • \e[m - La séquence d'échappement ANSI qui réinitialise la couleur.
  • >&2 - Sténographie pour 1>&2, cela redirige sedde stdout à stderr.
  • 3>&1 - Redirige le descripteur de fichier temporaire 3 retour dans stdout.

72
2018-04-23 20:53



+1 meilleure réponse! absolument sous-estimé! - muhqu
Grande réponse et explication encore meilleure - Daniel Serodio
Pourquoi avez-vous besoin de faire toute la redirection supplémentaire? semble exagéré - qodeninja
@qodeninja L'explication donne le but de la redirection. Si vous pouvez trouver un moyen plus simple de le faire, j'aimerais le voir! - killdash9
Y at-il un moyen de le faire fonctionner dans zsh? - Eyal Levin


Vous pouvez également vérifier stderred: https://github.com/sickill/stderred


23
2017-12-13 21:40



Wow, cet utilitaire est génial, la seule chose dont il aurait besoin est d’avoir un référentiel apt qui l’installe pour tous les utilisateurs, avec une ligne, sans avoir à faire plus de travail pour l’activer. - sorin
Cela semblait bien fonctionner lorsque je l’ai testé avec un script de compilation dans un terminal séparé, mais j’ai hésité à l’utiliser globalement .bashrc). Merci quand même! - Joel Purra
Dans OS X El Capitan, la façon dont cela fonctionne (DYLD_INSERT_LIBRARIES) est "interrompue" dans les fichiers binaires du système, car ils sont protégés par SIP. Il serait donc préférable d’utiliser les options bash données dans d’autres réponses. - hmijail
@hmijail pour MacOS veuillez suivre github.com/sickill/stderred/issues/60 nous pouvons donc trouver une solution de contournement, une solution partielle existe déjà, mais elle est un peu buggée. - sorin


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


14
2017-08-26 21:18





La façon de faire bash stderr de manière permanente, le rouge utilise 'exec' pour rediriger les flux. Ajoutez ce qui suit à votre base:

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;'

J'ai posté sur ceci précédemment: Comment définir la couleur de police pour STDOUT et STDERR


11
2018-01-29 08:49



en relation: unix.stackexchange.com/questions/367636/… - Blauhirn
C'est de loin la meilleure réponse. facile à mettre en œuvre sans installation / nécessitant le privilège sudo, et pouvant être généralisé à toutes les commandes. - Luke Davis
Malheureusement, cela ne fonctionne pas bien avec l'enchaînement des commandes (commande && nextCommand || errorHandlerCommand). La sortie d'erreur va après la sortie de errorHandlerCommand. - carlin.scott
De même, si je source ~/.bashrc deux fois avec cela, mon terminal se verrouille essentiellement. - Dolph
@Dolf: Dans mon panier, je garde facilement cela avec une instruction if entourant d'empêcher ce code de recharger. Sinon, le problème est la redirection 'exec 9> & 2' après que la redirection a déjà eu lieu. Peut-être changer la constante si vous savez où> 2 pointe à l'origine. - gospes


J'ai créé un script de wrapper qui implémente la réponse de Balázs Pozsár en pure bash. Enregistrez-le dans vos commandes $ PATH et préfixe pour coloriser leur sortie.


    #! / bin / bash

    if [$ 1 == "--help"]; puis
        echo "Exécute une commande et colorise toutes les erreurs survenues"
        echo "Exemple:` basename $ {0} `wget ..."
        echo "(c) o_O Tync, ICQ # 1227-700, profitez-en!"
        sortie 0
        Fi

    # Fichier temporaire pour attraper toutes les erreurs
    TMP_ERRS = $ (mktemp)

    # Commande exécuter
    "$ @" 2>> (pendant la lecture de la ligne; echo -e "\ e [01; 31m $ line \ e [0m" | tee --append $ TMP_ERRS; done)
    EXIT_CODE = $?

    # Affiche à nouveau toutes les erreurs
    if [-s "$ TMP_ERRS"]; puis
        echo -e "\ n \ n \ n \ e [01; 31m === ERREURS === \ e [0m"
        cat $ TMP_ERRS
        Fi
    rm -f $ TMP_ERRS

    # Terminer
    quitter $ EXIT_CODE


7
2017-08-26 22:13



Cela pourrait être rendu plus efficace si "| tee ..." était ajouté après "done". - Juliano


Vous pouvez utiliser une fonction comme celle-ci


 #!/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



Ne pas résoudre le problème. Vous n'avez pas fourni de moyen de séparer stderr de stdout, ce qui intéresse O.P. - Jeremy Visser


J'ai une version légèrement modifiée du script de O_o Tync. J'avais besoin de créer ces mods pour OS X Lion et ce n'est pas parfait car le script se termine parfois avant la commande encapsulée. J'ai ajouté un sommeil mais je suis sûr qu'il y a un meilleur moyen.

#!/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