Sobre sua pergunta de desempenho, os pipes são mais eficientes que os arquivos, porque não é necessário E / S de disco. Portanto, cmd1 | cmd2
é mais eficiente do que cmd1 > tmpfile; cmd2 < tmpfile
(isso pode não ser verdade se tmpfile
for feito backup em um disco RAM ou outro dispositivo de memória como pipe nomeado; mas se for um pipe nomeado, cmd1
deverá ser executado em segundo plano, pois sua saída poderá bloquear se o pipe ficar cheio ) Se você precisar do resultado cmd1
e ainda precisar enviar sua saída cmd2
, deverá cmd1 | tee tmpfile | cmd2
permitir cmd1
e cmd2
executar em paralelo evitando operações de leitura de disco cmd2
.
Os pipes nomeados são úteis se muitos processos forem lidos / gravados no mesmo pipe. Eles também podem ser úteis quando um programa não foi projetado para usar stdin / stdout, pois sua E / S precisa de arquivos . Coloquei os arquivos em itálico, porque os pipes nomeados não são exatamente arquivos no ponto de vista de armazenamento, pois residem na memória e têm um tamanho de buffer fixo, mesmo se tiverem uma entrada do sistema de arquivos (para fins de referência). Outras coisas no UNIX têm 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 bloquear, 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? As regras sobre esse comportamento são bem definidas e podem ser encontradas no homem.
Uma coisa que você não pode fazer com os pipes (nomeados e não nomeados) é procurar 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 o arquivo. Os pipes sem nome não têm 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 pipe (e soquete) sem nome. Não acho que possamos dizer isso "everything in Linux/Unix is a file"
, mas certamente podemos dizer isso "most IO in Linux/Unix is done using a file descriptor"
.