Como funcionam os pipes e os fluxos infinitos?

Como funcionam os pipes e os fluxos infinitos?

Costumo usar command1 | command2 | command3muito no Linux, mas a maioria deles lida com conteúdo definido.

Quando tentei isso com um fluxo infinito cat | sed '' | sed ''que, esperançosamente, simula um fluxo infinito, não funcionou até que eu o terminei com Ctrl-D. Posso resolver o problema com o uso cat | sed -e '' -e ''mas gostaria de saber porque o primeiro não funciona. cat | cat | catfunciona muito bem. Tem algo a ver com sed, em caso afirmativo, qual é o problema?

Tentei pensar nesse problema e a única coisa que achei diferente foi que quando estou usando catbato na Entertecla que faz algo especial que não está acontecendo no primeiro sed ''acima?

Alguém pode me informar como fazer o tubo funcionar perfeitamente com vapores infinitos?

Responder1

Os tubos conectam a saída ou o comando esquerdo à entrada do comando direito. Isso não tem nada a ver com a duração do fluxo. No entanto, cada comando no pipeline ainda possui suas próprias regras de buffer. Se você não ativá-los em cada comando, não os verá na saída final.

Responder2

Isso é basicamente uma duplicata deminha resposta no SO. No entanto, como ninguém mencionou o stdbufcomando aqui, achei que deveria adicioná-lo aqui também.

===============

Basicamente, um processo que lê de um pipe pode consumir os dados byte por byte assim que eles estiverem disponíveis no pipe. No entanto, desde que os programas estejam usando funções std io da libc, como leitura, gravação, etc., a libc irá armazenar em buffer a entrada/saída desses programas, dependendo se um programa está gravando em um terminal ou não.

Por padrão, se um programa estiver gravando em um terminal, a libc irá armazenar em buffer a linha de saída; se não for para um terminal, ela será armazenada em bloco em buffer.

No Linux, com glibc, você pode influenciar esse comportamento usando o stdbufcomando, assim:

stdbuf -oL cat | stdbuf -ioL sed '' | stdbuf -iL sed ''

Estou usando um buffer de saída baseado em linha para o catcomando, um buffer de entrada e saída baseado em linha para o primeiro sedcomando e um buffer de entrada baseado em linha para o último sedcomando.

Responder3

Você poderia usar a -uopção sed para minimizar o buffer:

cat | sed -u '' | sed ''

informação relacionada