Quero configurar meu terminal para que stderr
seja impresso em uma cor diferente de stdout
; talvez vermelho. Isso tornaria mais fácil diferenciar os dois.
Existe uma maneira de configurar isso .bashrc
? Caso contrário, isso é possível?
Nota : Esta pergunta foi fundida com outra que pediu stderr
, stdout
e a entrada do usuário ecoar a ser saída em 3 cores diferentes . As respostas podem estar abordando qualquer uma das perguntas.
Respostas:
Esta é uma versão mais difícil de Mostrar apenas stderr na tela, mas grave stdout e stderr no arquivo .
Os aplicativos em execução no terminal usam um único canal para se comunicar com ele; os aplicativos têm duas portas de saída, stdout e stderr, mas ambos estão conectados ao mesmo canal.
Você pode conectar um deles a um canal diferente, adicionar cor a esse canal e mesclar os dois canais, mas isso causará dois problemas:
␛[31m
significa "mudar para o primeiro plano vermelho". Isso significa que, se alguma saída destinada ao stdout chegar, assim como alguma saída do stderr estiver sendo exibida, a saída será diferente. (Pior ainda, se houver uma troca de canal no meio de uma sequência de escape, você verá lixo.)Em princípio, seria possível escrever um programa que escute em dois ptys¹, de forma síncrona (ou seja, não aceitará entrada em um canal enquanto estiver processando a saída no outro canal) e imediatamente envia para o terminal com instruções de alteração de cor apropriadas. Você perderia a capacidade de executar programas que interagem com o terminal. Não conheço nenhuma implementação desse método.
Outra abordagem possível seria fazer com que o programa produzisse as seqüências apropriadas de mudança de cor, conectando todas as funções libc que chamam a chamada do
write
sistema em uma biblioteca carregadaLD_PRELOAD
. Veja a resposta de sickill para uma implementação existente ou a resposta de Stéphane Chazelas para uma abordagem mista que aproveitastrace
.Na prática, se aplicável, sugiro redirecionar stderr para stdout e canalizar para um colorizador baseado em padrões, como colortail ou multitail , ou colorizadores para fins especiais, como colorgcc ou colormake .
¹ pseudo-terminais. Os tubos não funcionariam por causa do buffer: a fonte poderia gravar no buffer, o que quebraria a sincronicidade com o colorizador.
fonte
LD_PRELOAD
truque para interceptarwrite
chamadas parece ser o mais adequado, IMO (mas, novamente, pode haver diferenças em certos sabores * nix.)write
por si só não iria funcionar como a maioria dos aplicativos não chamar diretamente, mas uma outra função de alguma biblioteca compartilhada (comoprintf
) que chamaria o originalwrite
write
invólucro syscall. Está embutido em outras funções no Glibc?write
viaLD_PRELOAD
como você descreve.Confira
stderred
. Ele usaLD_PRELOAD
para ligar paralibc
aswrite()
chamadas, colorindo toda astderr
saída que vai para um terminal. (Em vermelho por padrão.)fonte
A coloração da entrada do usuário é difícil porque, na metade dos casos, ela é emitida pelo driver do terminal (com eco local); nesse caso, nenhum aplicativo em execução nesse terminal pode saber quando o usuário digitará o texto e alterará a cor de saída de acordo. . Somente o driver do pseudo-terminal (no kernel) sabe (o emulador de terminal (como o xterm) envia alguns caracteres ao pressionar algumas teclas e o driver do terminal pode enviar alguns caracteres de volta para eco, mas o xterm não pode saber se eles são do eco local ou a partir da saída do aplicativo para o lado escravo do pseudo terminal).
E há o outro modo em que o driver do terminal é instruído a não ecoar, mas o aplicativo dessa vez gera algo. O aplicativo (como aqueles que usam readline como gdb, bash ...) pode enviar isso em seu stdout ou stderr, o que dificulta a diferenciação de algo que ele gera para outras coisas além de ecoar a entrada do usuário.
Então, para diferenciar o stdout de um aplicativo do stderr, existem várias abordagens.
Muitos deles envolvem o redirecionamento dos comandos stdout e stderr para pipes e esses pipes são lidos por um aplicativo para colori-lo. Existem dois problemas com isso:
Outra abordagem é modificar o aplicativo para colorir seu stdout e stdin. Muitas vezes não é possível ou realista de fazer.
Então, um truque (para aplicativos vinculados dinamicamente) pode ser seqüestrar (usando
$LD_PRELOAD
como na resposta de sickill ) as funções de saída chamadas pelo aplicativo para produzir algo e incluir código nelas que define a cor do primeiro plano com base no objetivo de produzir algo em stderr ou stdout. No entanto, isso significa seqüestrar todas as funções possíveis da biblioteca C e de qualquer outra biblioteca quewrite(2)
execute um syscall diretamente chamado pelo aplicativo que possa acabar escrevendo algo em stdout ou stderr (printf, puts, perror ...) e, mesmo assim, , que pode modificar seu comportamento.Outra abordagem poderia ser usar truques PTRACE como
strace
ougdb
fazer para se conectar sempre que awrite(2)
chamada do sistema for chamada e definir a cor da saída com base nowrite(2)
descritor de arquivo 1 ou 2.No entanto, isso é algo muito importante a se fazer.
Um truque com o qual acabei de brincar é sequestrar a
strace
si próprio (que faz o trabalho sujo de ligar-se antes de cada chamada do sistema) usando LD_PRELOAD, para dizer a ele para alterar a cor de saída com base em se detectou umwrite(2)
no fd 1 ou 2)De olhar para
strace
o código-fonte, podemos ver que tudo o que produz é feito através davfprintf
função. Tudo o que precisamos fazer é invadir essa função.O wrapper LD_PRELOAD se pareceria com:
Em seguida, compilamos com:
E use-o como:
Você notará como, se você substituir
some-cmd
porbash
, o prompt do bash e o que você digitar aparecer em vermelho (stderr) enquantozsh
estiver em preto (porque zsh dups stderr em um novo fd para exibir seu prompt e eco).Parece funcionar surpreendentemente bem, mesmo para aplicativos que você não esperaria (como aqueles que usam cores).
O modo de coloração é emitido no
strace
stderr do que é assumido como o terminal. Se o aplicativo redirecionar seu stdout ou stderr, nosso rastreamento seqüestrado continuará gravando as seqüências de escape de cores no terminal.Essa solução tem suas limitações:
strace
: problemas de desempenho, você não pode executar outros comandos ptrace comostrace
ougdb
na mesma, ou questões setuid / setgidwrite
padrões stdout / stderr de cada processo individual. Assim, por exemplo, emsh -c 'echo error >&2'
,error
seria verde porque oecho
exibe em seu stdout (o qual sh redirecionou para o stderr de sh, mas tudo que o strace vê é awrite(1, "error\n", 6)
). Esh -c 'seq 1000000 | wc'
, comoseq
faz muito ou nãowrite
ao seu padrão, o wrapper acaba gerando muitas seqüências de escape (invisíveis) no terminal.fonte
strace $CMD | vim -c ':set syntax=strace' -
.Aqui está uma prova de conceito que fiz um tempo atrás.
Funciona apenas no zsh.
Também pressupõe que você tenha uma função chamada setcolor.
Uma versão simplificada:
fonte
exec 2> >(rederr)
. Ambas as versões terão os problemas mencionados na minha resposta, de reordenar linhas e arriscar uma saída mutilada (particularmente com longas filas).seterr
teria que ser um script independente, não uma função.Veja Mike Schiraldi Hilite que faz isso para um comando de cada vez. Meu próprio jato faz isso por toda uma sessão, mas também possui muitos outros recursos / idiossincrasias que você pode não querer.
fonte
Alguma discussão anterior sobre falha do servidor.
Veja também grc e um blog útil sobre isso.
fonte