Isso é bem descrito aqui e aqui .
Então, no seu exemplo:
cat file | wc -l
A saída produzida por cat é direcionada para o fluxo stdout que está conectado via pipe ao fluxo stdin de wc .
Quanto à implementação real, cada canal é associado a um buffer de um determinado tamanho. Esse buffer é preenchido com dados de stdout do processo à esquerda e consumido por stdin do processo à direita. Ambos os processos estão sendo executados em paralelo e existe um mecanismo para bloquear o processo à esquerda, caso o processo correto não consiga consumir todos os dados com rapidez suficiente e o buffer esteja sendo preenchido.
Para mais detalhes, consulte aqui .