Eu acho que o bash nunca colorirá sua saída: algum programa pode querer analisar algo, e a coloração estragará os dados com seqüências de escape. Um aplicativo GUI deve lidar com cores, eu acho.
kolypto
A combinação da resposta de Balázs Pozsár e killdash9 fornece o nítido: function color { "$@" 2> >(sed $'s,.*,\e[31m&\e[m,') } funciona para o bash e o zsh. Não é possível adicionar isso como resposta b / c reputação.
Heinrich Hartmann
1
Estou aguardando uma resposta que modifique o bash para fazer isso. As soluções a seguir, todos efectivamente modificar stderr e, possivelmente, até mesmo o reordenar wrt saída padrão o qual quebra as coisas, quando a sequência de bytes exacta de stderr deve ser preservada por exemplo quando tubagem.
Ótimo! Mas eu me pergunto se há uma maneira de torná-lo :) permanente
kolypto
9
Ótima dica! Sugestão: Ao adicionar >&2um pouco antes ; done), a saída destinada ao stderr é realmente gravada no stderr. Isso é útil se você deseja capturar a saída normal do programa.
henko
8
As seguintes utilizações tput, e é ligeiramente mais legível na minha opinião:command 2> >(while read line; do echo -e "$(tput setaf 1)$line$(tput sgr0)" >&2; done)
Stefan Lasiewski
2
Eu acho que a execução de 2 processos de tput para cada linha de saída não é nada elegante. Talvez se você armazenasse a saída dos comandos tput em uma variável e os usasse para cada eco. Mas, novamente, a legibilidade não é realmente melhor.
Balázs Pozsár
1
Esta solução não preserva o espaço em branco, mas eu gosto por sua brevidade. IFS= read -r linedeve ajudar, mas não ajuda. Não sei por que.
Ambos os métodos mostrarão os comandos stderrem vermelho.
Continue lendo para obter uma explicação de como o método 2 funciona. Existem alguns recursos interessantes demonstrados por este comando.
color()... - Cria uma função bash chamada cor.
set -o pipefail- Esta é uma opção de shell que preserva o código de retorno de erro de um comando cuja saída é canalizada para outro comando. Isso é feito em um subshell, criado pelos parênteses, para não alterar a opção de pipefail no shell externo.
"$@"- Executa os argumentos para a função como um novo comando. "$@"é equivalente a"$1" "$2" ...
2>&1- Redireciona o stderrdo comando para stdoutmodo que se torna sed's stdin.
>&3- Abreviação de 1>&3, isso redireciona stdoutpara um novo descritor de arquivo temporário 3. 3é roteado de volta para stdoutmais tarde.
sed ...- Por causa dos redirecionamentos acima, sed's stdiné o stderrcomando executado. Sua função é cercar cada linha com códigos de cores.
$'...' Uma construção bash que faz com que ele entenda caracteres com escape de barra invertida
.* - Corresponde a linha inteira.
\e[31m - A sequência de escape ANSI que faz com que os seguintes caracteres fiquem vermelhos
&- O sedcaractere de substituição que se expande para toda a cadeia correspondente (a linha inteira nesse caso).
\e[m - A sequência de escape ANSI que redefine a cor.
>&2- Abreviação para 1>&2, este redireciona sed's stdoutpara stderr.
3>&1- Redireciona 3novamente o descritor de arquivo temporário stdout.
Por que você precisa fazer todo o redirecionamento adicional? parece um exagero
qodeninja
1
Existe uma maneira de fazê-lo funcionar zsh?
Eyal Levin
1
O ZSH não reconhece os formulários de redirecionamento abreviado. Ele só precisa de mais dois zsh: color()(set -o pipefail;"$@" 2>&1 1>&3|sed $'s,.*,\e[31m&\e[m,'1>&2)3>&1
Uau, esse utilitário é ótimo, a única coisa que ele precisa é ter um repositório apt que o instale para todos os usuários, com uma linha, sem ter que fazer mais trabalho para habilitá-lo.
22412
Parecia funcionar bem quando o testei com um script de construção em um terminal separado, mas hesito em usá-lo globalmente (in .bashrc). Obrigado embora!
Joel Purra
2
No OS X El Capitan, a maneira como isso funciona (DYLD_INSERT_LIBRARIES) é "interrompida" nos binários do sistema porque eles são protegidos pelo SIP. Portanto, pode ser melhor usar as opções do bash fornecidas em outras respostas.
hmijail
1
@hmijail para MacOS, siga github.com/sickill/stderred/issues/60 para encontrar uma solução alternativa, uma parcial já existe, mas é um pouco problemática.
sorin
15
A maneira básica de tornar o stderr permanentemente vermelho é usar 'exec' para redirecionar fluxos. Adicione o seguinte ao seu bashrc:
Esta é a melhor resposta de longe; É fácil de implementar sem a instalação / requer privilégio sudo e pode ser generalizado para todos os comandos.
Luke Davis
1
Infelizmente, isso não funciona bem com o encadeamento de comandos (comando && nextCommand || errorHandlerCommand). A saída de erro segue a saída errorHandlerCommand.
Carlin.scott 18/06/19
1
Da mesma forma, se eu fizer isso source ~/.bashrcduas vezes, meu terminal basicamente trava.
Dolph
@Dolf: No meu bashrc, eu me protejo facilmente com uma declaração if circundante para impedir que esse código seja recarregado. Caso contrário, o problema é o redirecionamento 'exec 9> & 2' após o redirecionamento já ter ocorrido. Talvez mude para uma constante se você souber para onde> 2 está apontando originalmente.
Eu criei um script de wrapper que implementa a resposta de Balázs Pozsár em pura festa. Salve-o em seus comandos $ PATH e prefix para colorir sua saída.
#! / bin / bash
if [$ 1 == "--help"]; então
echo "Executa um comando e colore todos os erros ocorridos"
echo "Exemplo:` nome da base $ {0} `wget ..."
eco "(c) o_O Tync, ICQ # 1227-700, divirta-se!"
saída 0
fi
# Arquivo temporário para capturar todos os erros
TMP_ERRS = $ (mktemp)
# Executar comando
"$ @" 2>> (enquanto lê a linha; faça eco-e "\ e [01; 31m $ line \ e [0m" | tee - adicione $ TMP_ERRS; pronto)
EXIT_CODE = $?
# Exibe todos os erros novamente
if [-s "$ TMP_ERRS"]; então
eco -e "\ n \ n \ n \ e [01; 31m === ERROS === \ e [0m"
cat $ TMP_ERRS
fi
rm -f $ TMP_ERRS
# Terminar
sair $ EXIT_CODE
Não está resolvendo o problema. Você não forneceu uma maneira de separar stderr de stdout, e é nisso que o OP está interessado.
Jeremy Visser
1
Eu tenho uma versão ligeiramente modificada do script do O_o Tync. Eu precisava fazer esses mods para o OS X Lion e não é perfeito porque o script às vezes é concluído antes do comando finalizado. Adicionei um sono, mas tenho certeza de que há uma maneira melhor.
#!/bin/bashif[ $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 0fi# 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 againif[-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
# Red STDERR# rse <command string>function rse(){# We need to wrap each phrase of the command in quotes to preserve arguments that contain whitespace# Execute the command, swap STDOUT and STDERR, colour STDOUT, swap back((eval $(for phrase in"$@";do echo -n "'$phrase' ";done))3>&11>&22>&3| sed -e "s/^\(.*\)$/$(echo -en \\033)[31;1m\1$(echo -en \\033)[0m/")3>&11>&22>&3}
function color { "$@" 2> >(sed $'s,.*,\e[31m&\e[m,') }
funciona para o bash e o zsh. Não é possível adicionar isso como resposta b / c reputação.Respostas:
fonte
>&2
um pouco antes; done)
, a saída destinada ao stderr é realmente gravada no stderr. Isso é útil se você deseja capturar a saída normal do programa.tput
, e é ligeiramente mais legível na minha opinião:command 2> >(while read line; do echo -e "$(tput setaf 1)$line$(tput sgr0)" >&2; done)
IFS= read -r line
deve ajudar, mas não ajuda. Não sei por que.Método 1: Usar substituição de processo:
Método 2: Crie uma função em um script bash:
Use-o assim:
Ambos os métodos mostrarão os comandos
stderr
em vermelho.Continue lendo para obter uma explicação de como o método 2 funciona. Existem alguns recursos interessantes demonstrados por este comando.
color()...
- Cria uma função bash chamada cor.set -o pipefail
- Esta é uma opção de shell que preserva o código de retorno de erro de um comando cuja saída é canalizada para outro comando. Isso é feito em um subshell, criado pelos parênteses, para não alterar a opção de pipefail no shell externo."$@"
- Executa os argumentos para a função como um novo comando."$@"
é equivalente a"$1" "$2" ...
2>&1
- Redireciona ostderr
do comando parastdout
modo que se tornased
'sstdin
.>&3
- Abreviação de1>&3
, isso redirecionastdout
para um novo descritor de arquivo temporário3
.3
é roteado de volta parastdout
mais tarde.sed ...
- Por causa dos redirecionamentos acima,sed
'sstdin
é ostderr
comando executado. Sua função é cercar cada linha com códigos de cores.$'...'
Uma construção bash que faz com que ele entenda caracteres com escape de barra invertida.*
- Corresponde a linha inteira.\e[31m
- A sequência de escape ANSI que faz com que os seguintes caracteres fiquem vermelhos&
- Osed
caractere de substituição que se expande para toda a cadeia correspondente (a linha inteira nesse caso).\e[m
- A sequência de escape ANSI que redefine a cor.>&2
- Abreviação para1>&2
, este redirecionased
'sstdout
parastderr
.3>&1
- Redireciona3
novamente o descritor de arquivo temporáriostdout
.fonte
zsh
?zsh: color()(set -o pipefail;"$@" 2>&1 1>&3|sed $'s,.*,\e[31m&\e[m,'1>&2)3>&1
Você também pode conferir stderred: https://github.com/sickill/stderred
fonte
.bashrc
). Obrigado embora!A maneira básica de tornar o stderr permanentemente vermelho é usar 'exec' para redirecionar fluxos. Adicione o seguinte ao seu bashrc:
Eu postei isso anteriormente: Como definir a cor da fonte para STDOUT e STDERR
fonte
source ~/.bashrc
duas vezes, meu terminal basicamente trava.http://sourceforge.net/projects/hilite/
fonte
Eu criei um script de wrapper que implementa a resposta de Balázs Pozsár em pura festa. Salve-o em seus comandos $ PATH e prefix para colorir sua saída.
fonte
Você pode usar uma função como esta
Anexo> & 2 para imprimir em stderr
fonte
Eu tenho uma versão ligeiramente modificada do script do O_o Tync. Eu precisava fazer esses mods para o OS X Lion e não é perfeito porque o script às vezes é concluído antes do comando finalizado. Adicionei um sono, mas tenho certeza de que há uma maneira melhor.
fonte
Esta solução funcionou para mim: https://superuser.com/questions/28869/immedately-tell-which-output-was-sent-to-stderr
Eu coloquei essa função no meu
.bashrc
ou.zshrc
:Então, por exemplo:
vai me dar uma saída vermelha.
fonte
set -o pipefail;
antes(eval
para o código de saída de redirecionamento"
to eval para preservar espaços nos argumentosusando xargs e printf:
fonte
uma versão usando fifos
fonte