Como funcionam os pipes e fluxos infinitos?

4

Eu costumo usar muito command1 | command2 | command3 no Linux, mas a maioria deles está lidando com conteúdo definido.

Quando eu tentei isso com um fluxo infinito cat | sed '' | sed '' que simula um fluxo infinito, ele não funcionou, mas terminei com Ctrl-D . Eu posso resolver o problema usando cat | sed -e '' -e '' , mas eu gostaria de saber porque o primeiro não funciona. cat | cat | cat funciona muito bem. É algo a ver com sed , em caso afirmativo, qual é esse problema?

Eu tentei pensar sobre esse problema e a única coisa que achei diferente foi que quando eu estou usando cat eu apertei a tecla Enter que faz algo especial que não está acontecendo no primeiro sed '' acima?

Alguém pode me informar como fazer o pipe funcionar perfeitamente com fluxos infinitos?

    
por Nishant 18.05.2016 / 16:13

3 respostas

5

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

    
por 18.05.2016 / 16:20
4

Isso é basicamente uma duplicata da minha resposta no SO . No entanto, como ninguém mencionou o comando stdbuf aqui, senti que também deveria acrescentar isso aqui.

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

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

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

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

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

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

    
por 18.05.2016 / 16:43
3

Você pode usar a opção -u de sed para minimizar o buffer:

cat | sed -u '' | sed ''
    
por 18.05.2016 / 16:18