Como entender os canos

20

Quando acabei de usar o pipe no bash, não pensei mais sobre isso. Mas quando eu leio algum exemplo de código C usando system call pipe () junto com fork (), eu me pergunto como entender os pipes, incluindo tanto pipes anônimos quanto pipes nomeados.

Muitas vezes é ouvido que "tudo no Linux / Unix é um arquivo". Gostaria de saber se um pipe é realmente um arquivo para que uma parte seja conectada ao arquivo de pipe e a outra parte seja lida do arquivo de pipe? Se sim, onde é criado o arquivo de pipe para um pipe anônimo? Em / tmp, / dev ou ...?

No entanto, a partir de exemplos de pipes nomeados, também aprendi que o uso de pipes tem vantagem de desempenho de espaço e tempo ao usar explicitamente arquivos temporários, provavelmente porque não há arquivos envolvidos na implementação de pipes. Além disso, os pipes não armazenam dados como os arquivos. Então duvido que um pipe seja realmente um arquivo.

    
por Tim 05.08.2011 / 14:25

4 respostas

22

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" .

    
por 05.08.2011 / 17:35
4

Dois dos fundamentos básicos da filosofia do UNIX são

  1. Para fazer pequenos programas que fazem uma coisa bem.
  2. e espera que a saída de cada programa se torne a entrada para outro, como o  ainda desconhecido, programa.

    O uso de tubos permite alavancar os efeitos desses dois projetos.  fundamentos para criar cadeias extremamente poderosas de comandos para alcançar  o resultado desejado.

    A maioria dos programas de linha de comando que operam em arquivos também podem aceitar entrada  entrada padrão (entrada pelo teclado) e saída para saída padrão (imprimir no teclado)  tela).

    Alguns comandos são projetados para operar somente dentro de um tubo e não podem operar  em arquivos diretamente.

    por exemplo, tr command

  ls -C | tr 'a-z' 'A-Z'
    cmd1 | cmd2
  • Envia STDOUT de cmd1 para STDIN de cmd2 em vez da tela.

  • STDERR não é encaminhado pelos canais.

    Em suma, Pipes is character (|) pode conectar comandos.

    Qualquer comando que grava em STDOUT pode ser usado no lado esquerdo  de tubo.

       ls - /etc | less 
    

    Qualquer comando que leia de STDIN pode ser usado no lado direito  lado de um tubo.

       echo "test print" | lpr 
    

    Um canal tradicional é "sem nome" porque existe anonimamente e persiste apenas enquanto o processo estiver em execução. Um pipe nomeado é persistente no sistema e existe além da vida útil do processo e deve ser excluído quando não estiver mais sendo usado. Os processos geralmente são anexados ao pipe nomeado (geralmente aparecendo como um arquivo) para executar comunicação entre processos (IPC).

fonte: link

    
por 05.08.2011 / 18:46
3

Para complementar as outras respostas ...

stdin e stdout são descritores de arquivos e são lidos e gravados como se fossem arquivos. portanto, você pode fazer echo hi | grep hi , e ele substituirá o stdout do eco por um pipe e substituirá o stdin do grep pela outra extremidade deste pipe.

    
por 05.08.2011 / 21:30
1

Tudo é um arquivo.

Se tomarmos a frase muito literalmente, acabaríamos com o significado de "só temos arquivos e nada mais". Esta não é a interpretação correta, então o que é.

Quando dizemos "Tudo é um arquivo", não estamos dizendo que tudo está armazenado em um disco. Estamos dizendo que tudo parece um arquivo, pode ser lido, pode ser escrito.

No Unix, uma vez que um arquivo ou não-arquivo esteja aberto, ele pode ser tratado como um arquivo. No entanto, nem todos os arquivos suportam todas as operações. Por exemplo. alguns arquivos (que não são arquivos), não suportam busca: eles devem ser lidos / escritos em sequência (isso é verdade para pipes e soquetes).

Tudo tem um nome de arquivo (em alguns sistemas: por exemplo, Debian GNU / Linux e muitos outros Gnu / Linux).

  • Todos os arquivos abertos recebem um nome de arquivo. Veja /proc/self/fd/…
  • Os soquetes de rede podem ser abertos com um nome de arquivo, consulte /dev/tcp
    por exemplo. %código%
por 23.09.2018 / 14:14