Eu quero tar
um diretório e gravar o resultado em stdout
, depois canalizá-lo para um programa de compactação, assim:
tar -cvf - /tmp/source-dir | lzip -o /media/my-usb/result.lz -
Eu tenho usado pipe o tempo todo com comandos que geram várias linhas de texto. Agora estou me perguntando o que aconteceria quando eu canalizasse um comando (rápido) com uma saída muito grande, como tar
e um comando de compactação muito lento seguido? Vai tar
esperar que sua saída seja consumida por lzip
? Ou apenas faz o mais rápido possível e envia tudo para a RAM? Será um desastre no sistema com pouca RAM se o último for verdade.
Quando o produtor de dados (
tar
) tenta escrever no pipe rápido demais para que o consumidor (lzip
) tenha tempo de ler tudo, ele bloqueia atélzip
ter tempo de ler o quetar
está escrevendo. Há um pequeno buffer associado ao pipe, mas seu tamanho provavelmente será menor do que o tamanho da maioria dostar
arquivos. Não há risco de encher a RAM do seu sistema com seu pipeline."Bloquear" significa simplesmente que, quando
tar
uma chamada para awrite()
função de biblioteca (ou equivalente), a chamada não retornará até que os dados sejam entregues ao buffer do pipe, o que pode levar um pouco de tempo selzip
for lento para ler a partir desse mesmo tampão. Você deve ser capaz de ver isso emtop
ondetar
ficaria mais lento e dormiria muito em comparação comlzip
(supondo quetar
seja de fato mais rápido quelzip
).Portanto, você não preencheria uma quantidade significativa de RAM com seu pipeline. Para fazer isso (se você quiser), você pode usar algo como
pv
no meio, com algum buffer grande (aqui, um gigabyte):Isso ainda bloquearia
tar
sempre quepv
bloquear.pv
bloquearia quando seu buffer estivesse cheio e não pudesse gravar emlzip
.A situação inversa funciona de maneira semelhante, ou seja, se você tiver um lado esquerdo lento de um pipe escrevendo para um lado direito rápido, o consumidor à direita bloquearia
read()
até que houvesse dados para serem lidos do pipe.Essa (E/S de dados) é a única coisa que sincroniza os processos que fazem parte de um pipeline. Além de ler e escrever (e ocasionalmente bloquear enquanto espera que alguém leia ou escreva), eles funcionariam independentemente um do outro.
O GNU tar tem a opção --lzip para "filtrar o arquivo através do lzip ", então você pode querer usar:
Respondendo à pergunta: no seu caso, o sistema gerenciará o pipe corretamente usando o tamanho padrão do buffer do sistema.