web-dev-qa-db-fra.com

Puis-je configurer mon shell pour imprimer stardr et stdout de différentes couleurs?

Je veux mettre mon trottoir à la finale afin de stderr est imprimé sous une couleur différente de stdout; peut-être rouge. Cela faciliterait la plus facile de dire les deux séparations.

Existe-t-il un moyen de configurer cela dans .bashrc? Sinon, est-ce encore possible?


Remarque : Cette question a été fusionnée avec ne autre qui a demandé stderr, stdout = Et l'entrée utilisateur echo Pour être sortie In 3 couleurs différentes. Les réponses peuvent être adressées à la question.

67
Naftuli Kay

Ceci est une version plus difficile de Afficher uniquement STDRER à l'écran, mais écrivez STDOUT et STDERR au fichier .

Les applications exécutées dans le terminal utilisent un seul canal pour communiquer avec elle; Les applications ont deux ports de sortie, STDOUT et STDERR, mais ils sont tous deux connectés au même canal.

Vous pouvez en connecter l'un à un canal différent, ajouter de la couleur à ce canal et fusionner les deux canaux, mais cela entraînera deux problèmes:

  • La production fusionnée peut ne pas être exactement dans le même ordre que s'il n'y avait pas eu de redirection. En effet, le traitement ajouté sur l'un des canaux prend (un peu) temps, de sorte que le canal coloré peut être retardé. Si un tampon est terminé, le trouble sera pire.
  • Les terminaux utilisent des séquences d'échappement changeant des couleurs pour déterminer la couleur d'affichage, par ex. ␛[31m signifie "passer au premier plan rouge". Cela signifie que si une sortie destinée à STDOUT arrive, tout comme certaines sorties pour STDRRR sont affichées, la sortie sera malolore. (Peu pire, s'il y a un commutateur de canal au milieu d'une séquence d'évacuation, vous verrez des ordures.)

En principe, il serait possible d'écrire un programme qui écoute sur deux ptys¹, de manière synchrone (c'est-à-dire d'accepter l'entrée sur un canal pendant son traitement de sortie sur l'autre canal) et se produit immédiatement sur le terminal avec des instructions de changement de couleur appropriées. Vous perdriez la capacité de lancer des programmes qui interagissent avec le terminal. Je ne connais aucune mise en œuvre de cette méthode.

Une autre approche possible serait de causer le programme de produire les séquences de changement de couleur correctes, en accrochant toutes les fonctions LIBC qui appellent l'appel système write dans une bibliothèque chargée avec LD_PRELOAD . Voir La réponse de malades Pour une implémentation existante, ou la réponse de Stéphane Chazelas Pour une approche mixte qui exploite strace.

En pratique, si cela est applicable, je suggère de rediriger STDERR sur STDOUT et de la tuyauterie dans un coloriseur à base de motifs tel que Colortail ou MULTIMIAIL ou colorizers spécial telle colorgcc ou colormake .

¹ pseudo-terminaux. Les tuyaux ne fonctionnaient pas à cause de la mise en mémoire tampon: la source pourrait écrire sur le tampon, ce qui briserait la synchronicité avec le coloriseur.

Vérifiez stderred . Il utilise LD_PRELOAD Pour accrocher à libc 's write() appels, colorant tout stderr sortie aller à un terminal. (En rouge par défaut.)

37
sickill

Voir Mike Schiraldi's Hilite qui fait cela pour une commande à la fois. My propre gush Cela pour toute une session, mais a également beaucoup d'autres caractéristiques/idiosyncragies que vous pourriez ne pas vouloir.

4
Colin Macleod

Voici une preuve de concept que j'ai fait un moment de retour.

Cela ne fonctionne que dans ZSH.

# make standard error red
rederr()
{
    while read -r line
    do
        setcolor $errorcolor
        echo "$line"
        setcolor normal
    done
}

errorcolor=red

errfifo=${TMPDIR:-/tmp}/errfifo.$$
mkfifo $errfifo
# to silence the line telling us what job number the background job is
exec 2>/dev/null
rederr <$errfifo&
errpid=$!
disown %+
exec 2>$errfifo

Cela suppose également que vous avez une fonction appelée SetColor.

Une version simplifiée:

setcolor()
{
    case "$1" in
    red)
        tput setaf 1
        ;;
    normal)
        tput sgr0
        ;;
    esac
}
4
Mikel

ne discussion antérieure sur Serverfault.

Voir aussi GRC et une utile blog à ce sujet.

1
anonfunc