Existe uma ferramenta para redirecionar dinamicamente a saída para um novo arquivo sob solicitação

8

No momento, estou redirecionando a saída de uma ferramenta de monitoramento para um arquivo; no entanto, o que eu gostaria de fazer é redirecionar essa saída para um novo arquivo a meu pedido (usando uma associação de teclas), sem interromper a dita ferramenta .

Algo como

monitor_program | handle_stdout

Onde handle_stdout me permite definir um novo arquivo onde colocar o log em determinado ponto.

Eu sei que poderia escrever isso facilmente, mas estou pensando se há alguma ferramenta que já permita isso.

    
por Treviño 04.05.2016 / 14:29

5 respostas

9

Vou sugerir um pipe nomeado.

  1. Crie um canal mkfifo p (chame como quiser, se não 'p')

  2. Crie um script "reader" que leia o canal e escreva onde quiser

  3. Diga ao programa de monitoramento para gravar seus logs no pipe nomeado

Aqui está um script de leitor de amostra que lê um pipe nomeado 'p' e grava os dados em um arquivo 'mylog' indexado:

#!/bin/sh

INDEX=0

switchlog() {
  read INDEX < newindex
  echo now writing to "mylog.$INDEX"
}

trap switchlog USR1

while :
do
  cat p >> mylog."$INDEX"
done
    
por 04.05.2016 / 15:08
7

Criando sua idéia SIGINT, aqui usando SIGQUIT ( Ctrl + \ ) você ainda pode usar Ctrl + C para parar tudo:

(trap '' QUIT; monitor_command) | (
   trap : QUIT
   ulimit -c 0 # prevent core dump so SIGQUIT behaves like SIGINT
               # for cat
   n=0; while n=$((n+1)); file=output.$n.log; do
     printf 'Outputting to "%s"\n' "$file"
     cat > "$file"
   done)

Isso pressupõe que cat não seja embutido em seu shell (portanto, ele é interrompido quando você pressiona Ctrl + \ ).

Note que, assim como na sua abordagem, há uma chance de o SIGQUIT ser entregue na hora errada (na chamada do sistema de gravação) fazendo com que alguns dados sejam perdidos.

    
por 04.05.2016 / 17:11
1

Você provavelmente poderia usar less e salvar a partir daí digitando s então o nome do arquivo que você deseja salvar, então Digite . De Como faço para escrever todas as linhas de menos para um arquivo? .

    
por 04.05.2016 / 14:52
0

Sem saber mais sobre o seu "pedido", não é realmente possível responder. Se fosse baseado no tamanho ou intervalo do arquivo, então rotatelogs (que deve vir junto com o Apache httpd ) funcionaria.

    
por 04.05.2016 / 14:58
0

Graças a resposta de Jeff Schaller , acabei com algo assim, que basicamente faz o que eu preciso, vamos chamá-lo de reader.sh :

#!/bin/sh

INDEX=0
LOGNAME="$INDEX.log"

switchlog() {
  local custom_name
  read -p "Add log name: " custom_name
  INDEX=$((INDEX+1))
  LOGNAME="$(printf "%03d" $INDEX).$custom_name.log"
  echo now writing to $LOGNAME
}

trap switchlog INT
switchlog

while :
do
  read foo < p
  printf "%s\n" "$foo" >> "$LOGNAME"
done

Depois, é só criar um canal nomeado com mkfifo p e usar dois terminais nos quais monitor_program > p e reader.sh estão em execução. Eu posso então parar o leitor para definir um novo log usando Ctrl + C , e digite um novo nome. Ctrl + Z , como de costume, para depois pará-lo e matá-lo.

    
por 05.05.2016 / 01:45