Je souhaite configurer mon terminal de manière à ce qu'il stderr
soit imprimé dans une couleur différente de celle de stdout
; peut-être rouge. Cela faciliterait la distinction entre les deux.
Y at-il un moyen de configurer cela dans .bashrc
? Si non, est-ce même possible?
Remarque : Cette question a été fusionnée avec une autre qui l’a demandé stderr
, stdout
et l’écho d’entrée de l’utilisateur doit être imprimé dans 3 couleurs différentes . Les réponses peuvent être adresser l'une ou l'autre question.
Réponses:
Ceci est une version plus difficile de Afficher uniquement stderr à l'écran, mais écrivez stdout et stderr dans un fichier .
Les applications exécutées dans le terminal utilisent un seul canal pour communiquer avec ce dernier. les applications ont deux ports de sortie, stdout et stderr, mais elles sont toutes deux connectées au même canal.
Vous pouvez connecter l'un d'entre eux à un autre canal, ajouter de la couleur à ce canal et fusionner les deux canaux, mais cela entraînera deux problèmes:
␛[31m
signifie par exemple «passer au premier plan rouge». Cela signifie que si une sortie destinée à stdout arrive juste au moment où une sortie pour stderr est affichée, la sortie sera mal colorée. (Pire encore, s'il y a un commutateur de canal au milieu d'une séquence d'échappement, vous verrez des déchets.)En principe, il serait possible d'écrire un programme qui écoute sur deux ptys¹ de manière synchrone (c'est-à-dire qu'il n'acceptera pas l'entrée sur un canal alors qu'il traite la sortie sur l'autre canal) et envoie immédiatement au terminal les instructions de changement de couleur appropriées. Vous perdriez la possibilité d'exécuter des programmes qui interagissent avec le terminal. Je ne connais aucune implémentation de cette méthode.
Une autre approche possible serait de forcer le programme à afficher les séquences de changement de couleur appropriées, en interceptant toutes les fonctions de la
write
bibliothèque appelant l' appel système dans une bibliothèque chargée avecLD_PRELOAD
. Voir la réponse de sickill pour une implémentation existante, ou la réponse de Stéphane Chazelas pour une approche mixte qui exploitestrace
.En pratique, si cela s’applique, je suggère de rediriger stderr vers stdout et de rediriger vers un coloriseur basé sur des motifs, tel que colortail ou multitail , ou des coloriseurs spéciaux, tels que colorgcc ou colormake .
¹ pseudo-terminaux. Les pipes ne fonctionneraient pas à cause de la mise en mémoire tampon: la source pourrait écrire dans la mémoire tampon, ce qui romprait la synchronicité avec le coloriseur.
la source
LD_PRELOAD
astuce pour intercepter deswrite
appels semble être le plus approprié, IMO (mais là encore, il pourrait y avoir des différences sur certains goûts * nix.)write
seule ne fonctionnerait pas car la plupart des applications n’appelaient pas directement, mais une autre fonction d’une bibliothèque partagée (commeprintf
) appelant l’originalwrite
write
wrapper Syscall. Est-il intégré dans d'autres fonctions de Glibc?write
via ceLD_PRELOAD
que vous décrivez.Consultez
stderred
. Il utiliseLD_PRELOAD
pour accrocher àlibc
l »write()
appel, colorisation tousstderr
sortie vers un terminal. (En rouge par défaut.)la source
La coloration de la saisie utilisateur est difficile car, dans la moitié des cas, elle est générée par le pilote de terminal (avec écho local). Dans ce cas, aucune application exécutée sur ce terminal ne peut savoir quand l’utilisateur va taper du texte et modifier la couleur de sortie en conséquence. . Seul le pilote du pseudo-terminal (dans le noyau) le sait (l’émulateur de terminal (comme xterm) lui envoie des caractères lorsqu’on appuie sur une touche et le pilote du terminal peut renvoyer des caractères pour l’écho, mais xterm ne peut pas savoir si ceux-ci proviennent du écho local ou de ce que l’application a envoyé au côté esclave du pseudo-terminal).
Et puis, il y a un autre mode dans lequel le pilote du terminal est invité à ne pas faire écho, mais l'application cette fois génère quelque chose. L'application (comme ceux qui utilisent readline comme gdb, bash ...) peut l'envoyer sur sa sortie standard ou stderr, ce qui sera difficile à différencier de quelque chose qu'elle génère pour autre chose que de renvoyer en écho les données entrées par l'utilisateur.
Ensuite, pour différencier la sortie standard d’une application de sa position standard, plusieurs approches sont possibles.
Beaucoup d'entre eux impliquent de rediriger les commandes stdout et stderr vers des tubes et ces tubes lus par une application pour le colorer. Cela pose deux problèmes:
Une autre approche consiste à modifier l’application afin qu’elle colore ses stdout et stdin. Il est souvent impossible ou réaliste de le faire.
Ensuite, une astuce (pour les applications liées dynamiquement) peut être de détourner (en utilisant
$LD_PRELOAD
comme dans la réponse de sickill ) les fonctions de sortie appelées par l'application pour produire quelque chose et y inclure du code qui définit la couleur de premier plan en fonction du type de sortie. sur stderr ou stdout. Cependant, cela signifie qu’il faut détourner toutes les fonctions possibles de la bibliothèque C et de toute autre bibliothèque qui effectue unwrite(2)
appel système directement appelé par l’application et qui pourrait éventuellement écrire quelque chose sur stdout ou stderr (printf, met, perror ...), et même alors. , cela peut modifier son comportement.Une autre approche pourrait consister à utiliser les astuces de PTRACE
strace
ou à lesgdb
utiliser pour se raccrocher chaque fois que l'write(2)
appel système est appelé et définir la couleur de sortie en fonction du typewrite(2)
de descripteur de fichier 1 ou 2.Cependant, c'est une très grosse chose à faire.
Une astuce que je viens de jouer consiste à détourner
strace
lui-même (qui fait le sale boulot de s’accrocher avant chaque appel système) en utilisant LD_PRELOAD, pour lui dire de changer la couleur de sortie en fonction du fait qu’il a détecté unwrite(2)
fd 1 ou 2En regardant
strace
le code source, nous pouvons voir que tout ce qu’il génère est réalisé via lavfprintf
fonction. Tout ce que nous devons faire est de détourner cette fonction.Le wrapper LD_PRELOAD ressemblerait à ceci:
Ensuite, nous le compilons avec:
Et utilisez-le comme:
Vous remarquerez que, si vous remplacez
some-cmd
parbash
, l'invite bash et ce que vous tapez apparaissent en rouge (stderr) et aveczsh
en noir (car zsh copie stderr sur un nouveau fd pour afficher son invite et son écho).Cela semble fonctionner étonnamment bien, même pour les applications auxquelles vous vous attendez (comme celles qui utilisent des couleurs).
Le mode de coloration est affiché sur
strace
le stderr qui est supposé être le terminal. Si l'application redirige son stdout ou stderr, notre strace détourné continuera à écrire les séquences d'échappement colorées sur le terminal.Cette solution a ses limites:
strace
: les problèmes de performances, vous ne pouvez pas exécuter d’autres commandes PTRACE telles questrace
ougdb
dans celle-ci, ni les problèmes de setuid / setgidwrite
s sur stdout / stderr de chaque processus. Ainsi, par exemple, danssh -c 'echo error >&2'
,error
serait vert car leecho
sort sur sa sortie standard (lequel sh est redirigé vers le statut de sh, mais tout ce que strace voit est awrite(1, "error\n", 6)
). Et insh -c 'seq 1000000 | wc'
,seq
fait beaucoup ouwrite
s sur sa sortie standard, le wrapper finira par envoyer beaucoup de séquences d'échappement (invisibles) au terminal.la source
strace $CMD | vim -c ':set syntax=strace' -
.Voici une preuve de concept que j'ai faite il y a longtemps.
Cela ne fonctionne que dans zsh.
Il suppose également que vous avez une fonction appelée setcolor.
Une version simplifiée:
la source
exec 2> >(rederr)
. Les deux versions présenteront les problèmes mentionnés dans ma réponse, à savoir réorganiser les lignes et risquer des sorties endommagées (en particulier avec les longues lignes).seterr
devrait être un script autonome, pas une fonction.Voir Mike Schiraldi Hilite qui le fait pour une commande à la fois. Mon propre gush fait cela pour toute une session, mais a aussi beaucoup d'autres fonctionnalités / idiosyncracies que vous pourriez ne pas vouloir.
la source
Quelques discussions précédentes sur serverfault.
Voir aussi grc et un blog utile à ce sujet.
la source