Os dados não precisam ser armazenados na RAM. Canos bloqueiam seus escritores se os leitores não estiverem lá ou não puderem acompanhar; no Linux (e na maioria das outras implementações, imagino) há algum armazenamento em buffer, mas isso não é obrigatório. Como mencionado por mtraceur e JdeBP (veja a resposta deste último ), versões anteriores de pipes Unix em buffer para o disco, e foi assim que eles ajudaram a limitar o uso de memória: um pipeline de processamento poderia ser dividido em pequenos programas, cada um processando alguns dados, dentro dos limites dos buffers de disco. Programas pequenos ocupam menos memória, e o uso de pipes significa que o processamento pode ser serializado: o primeiro programa rodará, preencherá o buffer de saída, será suspenso, o segundo programa será programado, o buffer será processado etc. Sistemas modernos são pedidos de magnitude maior que os primeiros sistemas Unix, e pode executar muitos pipes em paralelo; mas, para grandes quantidades de dados, você ainda veria um efeito semelhante (e variantes desse tipo de técnica são usadas para o processamento de "big data").
No seu exemplo,
sed 'simplesubstitution' file | sort | uniq > file2
sed
lê os dados de file
, conforme necessário, e grava-os enquanto sort
estiver pronto para lê-los; Se sort
não estiver pronto, os blocos de gravação. Os dados, na verdade, vivem na memória, mas isso é específico para sort
e sort
está preparado para lidar com quaisquer problemas (ele usará arquivos temporários, pois a quantidade de dados para classificar é muito grande).
Você pode ver o comportamento de bloqueio executando
strace seq 1000000 -1 1 | (sleep 120; sort -n)
Isso produz uma boa quantidade de dados e os canaliza para um processo que não está pronto para ler qualquer coisa nos primeiros dois minutos. Você verá uma série de write
das operações, mas muito rapidamente seq
irá parar e aguardar os dois minutos serem bloqueados pelo kernel (a chamada do sistema write
).