Estou alterando scripts no trabalho que monitoram arquivos de log para destacar determinados itens e colori-los. A saída final é uma lista de números de 6 dígitos em várias colunas. Consegui adicionar um ~
ao início do número e isso não quebra nada na saída final, mas é bastante feio e difícil de ler. No entanto, quando tento colorir o número, seja em scripts bash anteriores ou no processamento final dos dados em um script perl, o texto colorido fica confuso.
Por exemplo, o número original, que colocarei em $num
:
123456
Eu insiro isso em perl (ou quase a mesma coisa em bash):
"\e[1;34m" . $num . "\e[0m"
E aqui está o que eu recebo:
[1;34m123456[0m
Eu também tentei isso, uma versão com escape, mas obtive a mesma coisa:
"\x1B[1;34m" . $num . "\x1B[0m"
Se isso faz diferença, aqui está a verdadeira pilha de scripts (é uma bagunça):
- Perl chamado dentro do shell script, que então canaliza para
grep
/cut
/etc. - shell script com mais
cut
/etc., depois canaliza para .pl - shell script observa essa saída
Talvez watch
não goste de cores então?
Não sei perl
muito bem, então acho que não faria mal nenhum mostrar o que estou vendo nas linhas impressas:
my $format = ("%-8s") x scalar(@{$a[0]});
printf("$format\n", @$_)
Responder1
Encontrei problemas de 'roubo de cores' comassistir, é porque watch usa um estilo de saída /bin/sh simples, que elimina qualquer cor, aliases, atalhos... a coisa toda!
Então eu juntei isso, coloquei no meu.bashrc, me permite usar todos os meus próprios aliases, atalhos e outros enfeites:
Usage:
watcher 20 'somecommand | apipe | grep'
O número é o atraso entre as atualizações, em segundos, o comando pode incluir qualquer coisa que você citar.
###### 'watch' workalike, lets me use my aliases and such
function watcher() { WATCHERTIME=$1 ; WATCHERFILE=/tmp/watcher$$ ; shift ; while true ; do WATCHERHEIGHT=$(($LINES - 5)) ; ( eval $* ) | tail -n ${WATCHERHEIGHT} > ${WATCHERFILE} 2>/dev/null; clear ; /bin/echo -n "Every ${WATCHERTIME} seconds - " ; date ; /bin/echo ; cat ${WATCHERFILE} ; \rm -f ${WATCHERFILE} ; /bin/echo ; /bin/echo "==" ; sleep ${WATCHERTIME} ; done ; }
Para decompô-lo:
function watcher()
{
WATCHERTIME=$1
WATCHERFILE=/tmp/watcher$$
shift
while true; do
WATCHERHEIGHT=$(($LINES - 5))
( eval $* ) | tail -n ${WATCHERHEIGHT} > ${WATCHERFILE} 2>/dev/null
clear
/bin/echo -n "Every ${WATCHERTIME} seconds - "
date
/bin/echo
cat ${WATCHERFILE}
\rm -f ${WATCHERFILE}
/bin/echo
/bin/echo "=="
sleep ${WATCHERTIME}
done
}
Ele determina a altura atual da tela em linhas, subtrai o suficiente para sua própria saída, executa repetidamente o comando fornecido, limpa a tela, exibe a saída e aguarda o próximo loop. Ele exibe um breve '==' na parte inferior para indicar que foi onde a saída terminou. Às vezes é útil saber disso.
Fiz dessa maneira para que houvesse o menor atraso possível na exibição. se você não capturar a saída e depois exibi-la, terá uma longa pausa e a saída... nojenta.
Como não atrapalha as cores, você obtém tudo o que está acostumado. Aproveitar!
Responder2
O problema é que watch
usa Curses e as curses
funções de saída de string funcionam em um framebuffer virtual com planos separados para caracteres e seus atributos/cores. Strings são enviadas para o framebuffer como estão, sem interpretação de diretiva de terminal. Para se proteger contra a destruição do estado terminal, Curses ignora ESC
(entre outras coisas), portanto watch
não fará cores por padrão.
Você pode consertar isso seguindo os sábios conselhos de qualquer umjw013ouLórnix: use watch --color
ou envolva seu script em algo como um while true; do clear; $SCRIPT; sleep 2; done
loop.
Responder3
Você provavelmente precisará da --color
opção watch
.