Redirecionado colorido Printf para registrar os resultados em arquivo binário

3

Eu tenho um roteiro bem escrito. O script funciona bem, o problema que tenho é com redirecionamento. Eu fiz o seguinte bloco para redirecionar para um arquivo de log:

log_location=/home/admin
exec > >(tee -i $log_location/health-check.log)
exec 2>&1
echo -e "Output will be saved at $log_location/health-check.log\n"

O script tem o seguinte para cores:

G="3[32m"
N="3[0m"
R="3[31m"
Y="3[33m"

A saída do console é impressa no formato colorido para os caracteres necessários. No entanto, quando eu menos o arquivo .log, ele acaba como um arquivo binário e, ao ver, vejo algo assim:

ESC[33mGSANESC[0m Service Status is              |ESC[32mUPESC[0m
ESC[33mMCSESC[0m Service Status is               |ESC[32mUPESC[0m
ESC[33mTomcatESC[0m Service Status is    |ESC[32mUPESC[0m
ESC[33mSchedulerESC[0m Service Status is         |ESC[31mDOWNESC[0m
ESC[33mMaintenanceESC[0m Service Status is       |ESC[31mSUSPENDEDESC[0m

Eu não me importo de ter saída não colorida nos arquivos de log. Existe uma maneira de fazer isso?

    
por suhas savkoor 15.05.2017 / 14:11

2 respostas

2

Poderíamos organizar um sed para remover os códigos de cores da saída que vai para o arquivo de log. Embora isso requeira obter a saída de tee para stdout e para um pipe, isso não é exatamente simples. Pode haver maneiras melhores do que o truque de redirecionamento de subshell. Isso parece funcionar com o Bash e o GNU sed, o stdout obtém um error vermelho, o arquivo de log não recebe códigos de cores:

#!/bin/bash
exec > >( (tee -a /dev/fd/7 | sed -Ee $'s/3''\[[0-9][0-9]?m//g ' > logfile) 7>&1 )
N=$'3[0m'
R=$'3[31m'
echo "${R}error${N}: foo"

Outra opção no shell que evita os efeitos com a reabertura de /dev/fd/N no Linux:

#!/bin/bash
exec > >(
        exec 7>logfile
        while IFS= read -r x ; do 
                echo "$x"
                x=${x//$'3'\[[0-9]m}
                x=${x//$'3'\[[0-9][0-9]m}
                echo "$x" >&7
        done    
)
N=$'3[0m'
R=$'3[31m'
echo "${R}error${N}: foo"

Embora isso, é claro, tenha problemas com bytes NUL, mas uma saída de log provavelmente não possui muitos deles. Possivelmente, um script em Perl seria melhor aqui.

Se você se importasse apenas com mensagens impressas a partir do script, poderia criar uma função para imprimir a mensagem tanto para stdout quanto para o arquivo de log e remover os códigos de cores do último. Isso não ajudaria a obter a saída dos comandos para o mesmo arquivo de log.

    
por 15.05.2017 / 14:39
0

Você pode usar um filtro sed / awk / ... para remover as definições de cor do log em um redirecionamento de canal baseado em tee (como sugerido pela resposta anterior),

... ou simplesmente gere uma saída de log incolor e deixe a própria ferramenta de visualização de registros lidar com a colorização: Por exemplo, multitail é uma boa ferramenta candidata para isso.

    
por 15.05.2017 / 15:33