Envie stdin para o console e o arquivo compactado

6

Estou executando um programa proprietário que gera saída de texto. Mais ou menos como um lenhador.

logger

Gostaria de ver essa saída no terminal para observar o servidor respirar e enviá-lo para um arquivo de texto. Então normalmente eu faria:

logger | tee /tmp/log.txt

Mas esses arquivos de log podem se tornar grandes o suficiente para sobrecarregar o espaço em disco das minhas VMs. Em vez de enviar o texto para um arquivo de texto descompactado, gostaria que ele fosse compactado imediatamente. Então eu posso fazer:

logger

em um terminal e

logger | gzip > /tmp/log.gz

em outro terminal. Mas isso não parece muito * nixy.

Existe uma maneira de fazer isso em um comando, semelhante ao uso de tee ? Aqui está o que eu estou indo, o que obviamente não vai funcionar, mas talvez você tenha a idéia:

logger | tee gzip > /tmp/log.txt
    
por John Dibling 15.08.2013 / 15:32

1 resposta

17

Com ksh93 , zsh ou bash :

logger | tee >(gzip > /tmp/log.txt.gz)

Isso usa esse recurso ksh chamado substituição de processo . >(gzip > /tmp/log.txt.gz) é substituído pelo caminho de um arquivo (normalmente algo como /dev/fd/something , mas que também pode ser um pipe nomeado temporário) que se refere ao fim da escrita de um cano. No outro (leitura) final desse pipe, o shell conecta a entrada padrão de um novo processo (executado em segundo plano) que executa o comando gzip .

Então, quando tee escreve para esse arquivo , ele está realmente enviando os dados para gzip .

Em sistemas com /dev/fd/n , você pode fazê-lo manualmente (com qualquer shell parecido com o Bourne, mas com ksh93) como:

{ logger | tee -a /dev/fd/3 | gzip > /tmp/log.txt.gz; } 3>&1

(embora nesse caso /dev/fd/3 se refira ao stdin original que disponibilizamos no descritor de arquivo 3 com 3>&1 , não ao pipe para gzip que aqui está apenas conectado a tee ' s stdout)

com zsh :

logger >&1 > >(gzip > /tmp/log.txt.gz)

Que usa o recurso zsh multios pelo qual zsh implementa uma espécie de tee internamente para redirecionar a mesma saída para mais de um arquivo (aqui o stdout original ( >&1 ) e o pipe para gzip usando a substituição do processo novamente.

O stdout de

logger será realmente o final de gravação de um pipe. No outro extremo do pipe está um processo de shell que lê e distribui as duas saídas como tee .

    
por 15.08.2013 / 15:40