Sobre a sua pergunta de desempenho, os pipes são mais eficientes que os arquivos porque não é necessário nenhum I / O de disco. Portanto, cmd1 | cmd2
é mais eficiente que cmd1 > tmpfile; cmd2 < tmpfile
(isso pode não ser verdade se tmpfile
for copiado em um disco RAM ou outro dispositivo de memória como pipe nomeado; mas se for um pipe nomeado, cmd1
deve ser executado em o fundo como sua saída pode bloquear se o tubo ficar cheio). Se você precisar do resultado de cmd1
e ainda precisar enviar sua saída para cmd2
, deverá cmd1 | tee tmpfile | cmd2
, o que permitirá que cmd1
e cmd2
sejam executados em paralelo, evitando operações de leitura de disco a partir de cmd2
. / p>
Os pipes nomeados são úteis se muitos processos lerem / escreverem no mesmo pipe. Eles também podem ser úteis quando um programa não é projetado para usar stdin / stdout para seu IO precisar usar arquivos . Eu coloco os arquivos em itálico porque os pipes nomeados não são exatamente arquivos em um ponto de vista de armazenamento, pois eles residem na memória e têm um tamanho de buffer fixo, mesmo que tenham uma entrada do sistema de arquivos (para propósito de referência). Outras coisas no UNIX possuem entradas do sistema de arquivos sem serem arquivos: pense em /dev/null
ou outras entradas em /dev
ou /proc
.
Como os pipes (nomeados e não nomeados) têm um tamanho de buffer fixo, as operações de leitura / gravação podem ser bloqueadas, fazendo com que o processo de leitura / gravação entre no estado IOWait. Além disso, quando você recebe um EOF ao ler de um buffer de memória? Regras sobre esse comportamento são bem definidas e podem ser encontradas no homem.
Uma coisa que você não pode fazer com pipes (named e unnamed) é buscar de volta nos dados. Como eles são implementados usando um buffer de memória, isso é compreensível.
Sobre "everything in Linux/Unix is a file"
, eu não concordo. Os pipes nomeados possuem entradas do sistema de arquivos, mas não são exatamente arquivos. Os pipes sem nome não possuem entradas do sistema de arquivos (exceto talvez em /proc
). No entanto, a maioria das operações de E / S no UNIX é feita usando a função de leitura / gravação que precisa de um descritor de arquivo , incluindo o pipe não nomeado (e o soquete). Eu não acho que podemos dizer que "everything in Linux/Unix is a file"
, mas certamente podemos dizer que "most IO in Linux/Unix is done using a file descriptor"
.