Eu tenho um script que sempre dá saída onde eu o redireciono para um arquivo, o que estou tentando fazer é girar o arquivo redirecionado, abaixo é onde eu inicio o script e o redireciono:
.
somecode
.
su - username -c "command >> /path/to/directory/output.txt" &
.
.
code continues..
e abaixo está o crontab que estou tentando criar:
cd /path/to/directory/
timestamp=`date "+%Y%m%d"`
mv ./output.txt ./logs/output.txt_$timestamp
touch output.txt
chmod 757 ./output.txt
gzip ./logs/output.txt_$timestamp
find ./logs/output.txt* -type f -mtime +2 | xargs rm
ou este também não conseguiu fazer o trabalho:
timestamp=`date "+%Y%m%d"`
cp ./output.txt ./logs/output.txt_$timestamp
echo "" > ./output.txt
gzip ./logs/output.txt_$timestamp
no primeiro código o script original falha e não funciona mais, e no segundo script não limpa o arquivo output.txt.
Existe uma maneira de fazer isso enquanto mantém o script funcionando? Observação; Estou executando o Unix Solaris.
Desde já, obrigado.
Responder1
Isso normalmente é feito adicionando umSIGHUPmanipulador que reinicia o comandodepois que algum outro comando (normalmente logrotate
) moveu o arquivo. Nos sistemas operacionais *nix, você pode mover arquivos enquanto eles estão sendo gravados (acredito com a ressalva de que eles ainda devem estar no mesmo sistema de arquivos); as linhas extras serão anexadas ao arquivo no novo local.
Responder2
Você realmente não pode alterar o redirecionamento de um processo em execução stdout
e/ou stderr
para um novo arquivo (veja a nota abaixo) (Essa é uma das razões pelas quais usar arquivos redirecionados stdout
ou stderr
como arquivos de log para processos de longa execução é umruimideia.)
Quando o processo é iniciado, os elementos de redirecionamento do comando são executados pelo shell que inicia o processo. O arquivo de destino é aberto e criado, se necessário, no modo adequado (anexar ou substituir) e possivelmente truncado para zero bytes, dependendo do modo de redirecionamento. Em seguida, o descritor de arquivo aberto é passado para o processo filho. Esse descritor de arquivo aberto é o único link para o arquivo redirecionado que o processo filho possui - literalmente. É um link para o arquivo.
E esse é um ponto importante - como um link direto para o arquivo, o descritor aberto está no mesmo nível da entrada do diretório do arquivo - o "nome do arquivo". Alterar esse nome ou até mesmo excluir essa entrada de diretório - como acontece com o rm
comando - não tem absolutamente nenhum efeito no descritor de arquivo aberto no processo.
A resposta de @ l0b0 está correta: os processos que precisam girar logs tendem a usar SIGHUP
manipuladores para fazer essas rotações, mas "rotacionar logs" não é tão simples no caso de saída redirecionada - como é nomeado o novo arquivo de saída? O processo filho não tem idéia de qual é o "nome" dele stdout
e/ou stderr
é - e o "arquivo" de saída pode nem ser um arquivo em primeiro lugar.
Esquemas de rotação de logs devem serprojetadono processo - o registro deve ser integrado de tal forma que as entradas de registro não se percam durante a rotação do arquivo de registro, por exemplo.
(Tudo bem, pode serpossívelpara alterar os fluxos stdout
/ stderr
para um processo em execução - mas é algo que precisa ser - novamente -projetadono processo. Não é algo que um binário pronto para uso bash
fará automaticamente se você enviar um SIGHUP
...)
Responder3
Muito obrigado pelas respostas, não consegui encontrar uma maneira de fazer isso, então, como solução alternativa, configurei o crontab para interromper o script original, fazer a rotação e reiniciá-lo fora do pico.