Eu tenho um script bash que é executado enquanto a máquina Linux estiver ligada. Eu começo como mostrado abaixo:
( /mnt/apps/start.sh 2>&1 | tee /tmp/nginx/debug_log.log ) &
Após o lançamento, posso ver o comando tee na saída do meu ps , conforme mostrado abaixo:
$ ps | grep tee
418 root 0:02 tee /tmp/nginx/debug_log.log
3557 root 0:00 grep tee
Eu tenho uma função que monitora o tamanho do log que o tee produz e mata o comando tee quando o log atinge um determinado tamanho:
monitor_debug_log_size() {
## Monitor the file size of the debug log to make sure it does not get too big
while true; do
cecho r "CHECKING DEBUG LOG SIZE... "
debugLogSizeBytes=$(stat -c%s "/tmp/nginx/debug_log.log")
cecho r "DEBUG LOG SIZE: $debugLogSizeBytes"
if [ $((debugLogSizeBytes)) -gt 100000 ]; then
cecho r "DEBUG LOG HAS GROWN TO LARGE... "
sleep 3
#rm -rf /tmp/nginx/debug_log.log 1>/dev/null 2>/dev/null
kill -9 `pgrep -f tee`
fi
sleep 30
done
}
Para minha surpresa, matar o comando tee também mata por instância start.sh. Por que é isso? Como posso encerrar o comando tee , mas fazer com que meu start.sh continue em execução? Obrigado.
Quando
tee
terminar, o comando que o alimenta continuará em execução, até tentar gravar mais saída. Em seguida, obterá um SIGPIPE (13 na maioria dos sistemas) por tentar gravar em um pipe sem leitores.Se você modificar seu script para interceptar o SIGPIPE e tomar alguma ação apropriada (como parar de gravar a saída), você poderá fazer com que ele continue depois que o tee for encerrado.
Melhor ainda, em vez de matar
tee
, uselogrotate
com acopytruncate
opção de simplicidade.Para citar
logrotate(8)
:Explicando o "porquê"
Resumindo: se as falhas de gravação não causassem a saída de um programa (por padrão), teríamos uma bagunça. Considere
find . | head -n 10
- você não querfind
continuar rodando, escaneando o resto do seu disco rígido, depoishead
de pegar as 10 linhas necessárias e prosseguir.Fazendo melhor: gire dentro do seu registrador
Considere o seguinte, que não usa
tee
nada, como um exemplo demonstrativo:Se executado como:
...isso começará anexando a
/tmp/nginx/debug_log
, renomeando o arquivo para/tmp/nginx/debug_log.old
quando houver mais de 100 KB de conteúdo. Como o próprio registrador está fazendo a rotação, não há tubo quebrado, nenhum erro e nenhuma janela de perda de dados quando a rotação ocorre - cada linha será gravada em um arquivo ou outro.Obviamente, implementar isso no bash nativo é ineficiente, mas o exemplo acima é ilustrativo. Existem vários programas disponíveis que implementarão a lógica acima para você. Considerar:
svlogd
, o registrador de serviços do pacote Runit.s6-log
, uma alternativa mantida ativamente da suíte skanet.multilog
da DJB Daemontools, o avô desta família de ferramentas de supervisão e monitoramento de processos.