Questão Qual é a diferença entre “Redirecionamento” e “Tubo”?


Esta questão pode parecer um pouco estúpida, mas eu não consigo realmente ver a diferença entre redirecionamento e pipes.

Redirecionamento é usado para redirecionar a stdout / stdin / stderr, por exemplo ls > log.txt.

Pipes são usados ​​para fornecer a saída de um comando como entrada para outro comando, por ex. ls | grep file.txt.

Mas por que existem dois operadores para a mesma coisa?

Por que não apenas escrever ls > grep para passar a saída, isso não é apenas um tipo de redirecionamento também? O que eu sinto falta?


174
2017-08-07 13:22


origem




Respostas:


O pipe é usado para transmitir a saída para outro programa ou utilitário.

O redirecionamento é usado para transmitir a saída para um arquivo ou fluxo.

Exemplo: thing1 > thing2 vs thing1 | thing2

thing1 > thing2

  1. Seu shell executará o programa chamado thing1
  2. Tudo que thing1 saídas serão colocados em um arquivo chamado thing2. (Nota - se thing2 existe, será sobrescrito)

Se você quiser passar a saída do programa thing1 para um programa chamado thing2, você poderia fazer o seguinte:

thing1 > temp_file && thing2 < temp_file

qual seria

  1. executar programa chamado thing1
  2. salve a saída em um arquivo chamado temp_file
  3. executar programa chamado thing2, fingindo que a pessoa no teclado digitou o conteúdo de temp_file como a entrada.

No entanto, isso é desajeitado, então eles fizeram tubos como uma maneira mais simples de fazer isso. thing1 | thing2 faz o mesmo que thing1 > temp_file && thing2 < temp_file

EDIT para fornecer mais detalhes para questionar no comentário:

E se > tentou ser tanto "passar para o programa" e "gravar no arquivo", poderia causar problemas em ambas as direções.

Primeiro exemplo: Você está tentando gravar em um arquivo. Já existe um arquivo com esse nome que você deseja sobrescrever. No entanto, o arquivo é executável. Presumivelmente, tentaria executar este arquivo, passando a entrada. Você teria que fazer algo como gravar a saída em um novo nome de arquivo e renomeá-lo.

Segundo exemplo: Como Florian Diesch apontou, e se houver outro comando em outro lugar no sistema com o mesmo nome (que está no caminho de execução). Se você pretendia criar um arquivo com esse nome em sua pasta atual, você estaria preso.

Em terceiro lugar: se você digitar um comando errado, ele não avisará que o comando não existe. Agora, se você digitar ls | gerp log.txt ele vai te dizer bash: gerp: command not found. E se > significou ambos, seria simplesmente criar um novo arquivo para você (então avise que ele não sabe o que fazer com log.txt).


195
2017-08-07 13:30



Obrigado. Você mencionou thing1 > temp_file && thing2 < temp_filefazer mais fácil com tubos. Mas por que não reutilizar o > operador para fazer isto, e. thing1 > thing2 para comandos thing1 e thing2 ? Por que um operador extra | ? - John Threepwood
"Pegue a saída e grave em um arquivo" é uma ação diferente de "Pegue a saída e passe para um programa diferente". Vou editar mais pensamentos na minha resposta ... - David Oneill
@ JohnThreepwood Eles têm significados diferentes. E se eu quisesse redirecionar algo para um arquivo chamado less, por exemplo? thing | less e thing > less são perfeitamente diferentes, como fazem coisas diferentes. O que você propõe criaria uma ambigüidade. - Darkhogg
É correto dizer que "thing1> temp_file" é meramente um açúcar sintático para "thing1 | tee temp_file"? Desde que descobri o tee, quase nunca uso redirecionamentos. - Sridhar-Sarnobat
@ Sridhar-Sarnobat não, o tee comando faz algo diferente. tee grava a saída na tela (stdout) e o arquivo. O redirecionamento não só o arquivo. - David Oneill


Se o significado de foo > bar dependeria se houvesse um comando chamado bar Isso tornaria o uso do redirecionamento muito mais difícil e mais propenso a erros: toda vez que eu quiser redirecionar para um arquivo, primeiro tive que verificar se há um comando com o nome do meu arquivo de destino.


19
2017-08-07 13:40



Isso seria um problema apenas se você está escrevendo para bar em um diretório que faz parte do seu $PATH variável env. Se você está em algo como / bin, então ot pode ser um problema. Mas mesmo assim, bar teria que ter o conjunto de permissão executável, para que o shell fosse verificado não apenas por encontrar um executável bar mas na verdade pode executá-lo. E se a preocupação é sobrescrever o arquivo existente, noclober A opção de shell deve impedir a substituição de arquivos existentes nos redirecionamentos. - Sergiy Kolodyazhnyy


Há uma diferença vital entre os dois operadores:

  1. ls > log.txt -> Este comando envia a saída para o arquivo log.txt.

  2. ls | grep file.txt -> Este comando envia a saída do comando ls para grep através do uso de pipe (|), e o comando grep procura o arquivo.txt na entrada fornecida pelo comando anterior.

Se você tivesse que executar a mesma tarefa usando o primeiro cenário, então seria:

ls > log.txt; grep 'file.txt' log.txt

Então um cachimbo (com |) é usado para enviar a saída para outro comando, enquanto o redirecionamento >) é usado para redirecionar a saída para algum arquivo.


11
2017-08-07 13:32





Do manual de administração do sistema Unix e Linux:

Redirecionamento

O shell interpreta os símbolos <,> e >> como instruções para redirecionar um Comando entrada ou saída para ou de um Arquivo.

Tubos

Para conectar o STDOUT de um comando para o STDIN de outro use o | símbolo, comumente conhecido como um tubo.

Então minha interpretação é: Se for comando para comando, use um pipe. Se você estiver enviando para ou de um arquivo, use o redirecionamento.


9
2018-02-16 00:40





Há uma grande diferença sintática entre os dois:

  1. Um redirecionamento é um argumento para um programa
  2. Um tubo separa dois comandos

Você pode pensar em redirecionamentos como este: cat [<infile] [>outfile]. Isso implica que a ordem não importa: cat <infile >outfile é o mesmo que cat >outfile <infile. Você pode até mesclar redirecionamentos com outros argumentos: cat >outfile <infile -b e cat <infile -b >outfile Ambos estão perfeitamente bem. Além disso, você pode agrupar mais de uma entrada ou saída (as entradas serão lidas sequencialmente e todas as saídas serão gravadas em cada arquivo de saída): cat >outfile1 >outfile2 <infile1 <infile2. O alvo ou fonte de um redirecionamento pode ser um nome de arquivo ou o nome de um fluxo (como & 1, pelo menos no bash).

Mas os canais separam totalmente um comando de outro comando, você não pode misturá-los com argumentos:

[command1] | [command2]

O pipe pega tudo escrito na saída padrão do command1 e o envia para a entrada padrão do comando2.

Você também pode combinar tubulação e redirecionamento. Por exemplo:

cat <infile >outfile | cat <infile2 >outfile2

O primeiro cat irá ler as linhas do infile, então, simultaneamente, escrever cada linha para outfile e enviá-lo para o segundo cat.

No segundo cat, a entrada padrão primeiro lê a partir do canal (o conteúdo do arquivo), então lê a partir do infile2, escrevendo cada linha para outfile2. Depois de executar isto, o outfile será uma cópia do infile e o outfile2 conterá o infile seguido pelo infile2.

Finalmente, você realmente faz algo realmente similar ao seu exemplo usando o redirecionamento "here string" (somente família bash) e backticks:

grep blah <<<`ls`

vai dar o mesmo resultado que

ls | grep blah

Mas acho que a versão de redirecionamento primeiro lerá toda a saída de ls em um buffer (na memória) e, em seguida, alimentará esse buffer para grep uma linha por vez, enquanto a versão canalizada tomará cada linha de ls quando surgir, e passe essa linha para grep.


3
2017-08-23 22:24



Nitpick: a ordem é importante no redirecionamento se você redirecionar um fd para outro: echo yes 1>&2 2>/tmp/blah; wc -l /tmp/blah; echo yes 2>/tmp/blah 1>&2; wc -l /tmp/blah Além disso, o redirecionamento para um arquivo usará somente o último redirecionamento. echo yes >/tmp/blah >/tmp/blah2 só vai escrever para /tmp/blah2. - muru
O redirecionamento não é realmente argumento para o programa. O programa não saberá ou não importará para onde vai sua saída (ou a entrada vem). É apenas uma maneira de dizer bash como organizar as coisas antes de executar o programa. - Alois Mahdal


Nota: A resposta reflete minha própria compreensão desses mecanismos até o momento, acumulada sobre pesquisa e leitura das respostas pelos pares neste site e unix.stackexchange.come será atualizado com o passar do tempo. Não hesite em fazer perguntas ou sugerir melhorias nos comentários. Eu também sugiro que você tente ver como funciona o syscalls no shell com strace comando. Também, por favor, não se deixe intimidar pela noção de internals ou syscalls - você não precisa saber ou ser capaz de usá-los para entender como o shell faz as coisas, mas eles definitivamente ajudam a compreensão.

TL; DR

  • | pipes não estão associados a uma entrada no disco, portanto, não tem um inode número de sistemas de arquivos em disco (mas tem inode em pipetas sistema de arquivos virtual no espaço do kernel), mas os redirecionamentos geralmente envolvem arquivos, que possuem entradas de disco e, portanto, possuem um inode correspondente.
  • canos não são lseek()'assim comandos não podem ler alguns dados e retroceder de volta, mas quando você redireciona com > ou < geralmente é um arquivo que é lseek() objeto capaz, então os comandos podem navegar do jeito que quiserem.
  • redirecionamentos são manipulações em descritores de arquivos, que podem ser muitos; pipes tem apenas dois descritores de arquivos - um para o comando esquerdo e outro para o comando direito
  • redirecionamento em fluxos e pipes padrão são ambos armazenados em buffer.
  • tubos quase sempre envolvem bifurcações, redirecionamentos - nem sempre
  • pipes sempre lidam com descritores de arquivos, redirecionamentos - use arquivos reais com nome de arquivo no disco ou descritores de arquivo.
  • pipes são o método de comunicação entre processos, enquanto os redirecionamentos são apenas manipulações em arquivos abertos ou objetos semelhantes a arquivos
  • ambos empregam dup2() syscalls sob o capô para fornecer cópias de descritores de arquivos, onde ocorre o fluxo real de dados.
  • redirecionamentos podem ser aplicados "globalmente" com exec comando interno (consulte esta e esta ), então se você fizer exec > output.txt cada comando vai escrever para output.txt a partir de então. | pipes são aplicados apenas para o comando atual (o que significa comando simples ou subshell como seq 5 | (head -n1; head -n2) ou comandos compostos.
  • Quando o redirecionamento é feito em arquivos, coisas como echo "TEST" > file e echo "TEST" >> file ambos usam open() syscall nesse arquivo (Veja também) e obter descritor de arquivo para passá-lo para dup2(). Tubos | use apenas pipe() e dup2() syscall.

Introdução

Para entender como esses dois mecanismos diferem, é necessário entender suas propriedades essenciais, a história por trás dos dois e suas raízes na linguagem de programação C. De fato, saber quais descritores de arquivos são e como dup2() e pipe() chamadas de sistema é essencial, assim como lseek(). Shell é uma forma de tornar esses mecanismos abstratos para o usuário, mas cavar mais fundo do que a abstração ajuda a entender a verdadeira natureza do comportamento da shell.

As Origens dos Redirecionamentos e Tubulações

De acordo com o artigo de Dennis Ritche Petróglifos Proféticos, tubos originados de um Memorando interno de 1964 de Malcolm Douglas McIlroy, no momento em que eles estavam trabalhando Sistema operacional Multics. Citar:

Para colocar minhas mais fortes preocupações em poucas palavras:

  1. Devemos ter algumas maneiras de conectar programas como mangueira de jardim - parafusar em outro segmento quando se torna necessário fazer massagens de dados de outra maneira. Este é o caminho de IO também.

O que é aparente é que, na época, os programas eram capazes de gravar em disco, no entanto, isso era ineficiente se a saída fosse grande. Para citar a explicação de Brian Kernighan em Pipeline do Unix vídeo :

Primeiro, você não precisa escrever um grande programa - você tem programas menores que já podem fazer parte do trabalho ... Outra é que é possível que a quantidade de dados que você está processando não se encaixe se você armazenou em um arquivo ... porque lembre-se, estamos de volta nos dias em que os discos dessas coisas tinham, se você tivesse sorte, um Megabyte ou dois de dados ... Então o pipeline nunca teve que instanciar toda a saída .

Assim, a diferença conceitual é aparente: os tubos são um mecanismo para fazer com que os programas conversem entre si. Redirecionamentos - são formas de escrever para arquivo no nível básico. Em ambos os casos, o shell torna essas duas coisas fáceis, mas sob o capô, há muita coisa acontecendo.

Indo mais fundo: syscalls e funcionamento interno do shell

Nós começamos com a noção de descritor de arquivo. Os descritores de arquivos descrevem basicamente um arquivo aberto (seja um arquivo no disco ou na memória ou um arquivo anônimo), que é representado por um número inteiro. Os dois fluxos de dados padrão  (stdin, stdout, stderr) são descritores de arquivo 0,1 e 2 respectivamente. De onde eles vêm ? Bem, nos comandos shell, os descritores de arquivos são herdados de seu shell pai. E é verdade em geral para todos os processos - o processo filho herda os descritores de arquivos do pai. Para daemons é comum fechar todos os descritores de arquivos herdados e / ou redirecionar para outros locais.

Voltar para o redirecionamento. O que é isso realmente? É um mecanismo que diz ao shell para preparar os descritores de arquivo para o comando (porque os redirecionamentos são feitos pelo shell antes da execução do comando) e apontá-los onde o usuário sugeriu. o definição padrão de redirecionamento de saída é

[n]>word

que [n] existe o número do descritor de arquivo. Quando você faz echo "Something" > /dev/null o número 1 está implícito lá, e echo 2> /dev/null.

Sob o capô isso é feito duplicando o descritor de arquivo via dup2() chamada do sistema. Vamos levar df > /dev/null. O shell criará um processo filho onde df corre, mas antes disso vai abrir /dev/null como descritor de arquivo # 3, e dup2(3,1) será emitido, o que faz uma cópia do descritor de arquivos 3 e a cópia será 1. Você sabe como tem dois arquivos file1.txt e file2.txte quando você faz cp file1.txt file2.txt você terá dois arquivos iguais, mas você pode manipulá-los independentemente? Essa é a mesma coisa acontecendo aqui. Muitas vezes você pode ver que antes de correr, o bash vai fazer dup(1,10) fazer um descritor de arquivo de cópia # 1, que é stdout (e essa cópia será fd # 10) para restaurá-lo mais tarde. Importante é notar que quando você considera comandos internos (que são parte do próprio shell, e não possuem nenhum arquivo /bin ou em outro lugar) ou Comandos simples em shell não interativo, o shell não cria um processo filho.

E então nós temos coisas como [n]>&[m] e [n]&<[m]. Isso é duplicar descritores de arquivos, que possuem o mesmo mecanismo dup2() só agora está na sintaxe do shell, convenientemente disponível para o usuário.

Uma das coisas importantes a se observar sobre o redirecionamento é que seu pedido não é fixo, mas é significativo para como o shell interpreta o que o usuário deseja. Compare o seguinte:

# Make copy of where fd 2 points , then redirect fd 2
$ ls -l /proc/self/fd/  3>&2  2> /dev/null
total 0
lrwx------ 1 user user 64 Sep 13 00:08 0 -> /dev/pts/0
lrwx------ 1 user user 64 Sep 13 00:08 1 -> /dev/pts/0
l-wx------ 1 user user 64 Sep 13 00:08 2 -> /dev/null
lrwx------ 1 runner user 64 Sep 13 00:08 3 -> /dev/pts/0
lr-x------ 1 user user 64 Sep 13 00:08 4 -> /proc/29/fd

# redirect fd #2 first, then clone it
$ ls -l /proc/self/fd/    2> /dev/null 3>&2
total 0
lrwx------ 1 user user 64 Sep 13 00:08 0 -> /dev/pts/0
lrwx------ 1 user user 64 Sep 13 00:08 1 -> /dev/pts/0
l-wx------ 1 user user 64 Sep 13 00:08 2 -> /dev/null
l-wx------ 1 user user 64 Sep 13 00:08 3 -> /dev/null
lr-x------ 1 user user 64 Sep 13 00:08 4 -> /proc/31/fd

O uso prático destes em scripts de shell pode ser versátil:

e muitos outros.

Encanamento com pipe() e dup2()

Então, como os canos são criados? Através da pipe() syscall, que terá como entrada uma matriz (aka lista) chamada pipefd de dois itens do tipo int (inteiro). Esses dois inteiros são descritores de arquivos. o pipefd[0] será a extremidade de leitura do tubo e pipefd[1] será o final da gravação. Então, em df | grep 'foo', grep receberá cópia de pipefd[0] e df vai ter uma cópia do pipefd[1]. Mas como ? Claro, com a magia de dup2() syscall. Para df no nosso exemplo, digamos pipefd[1] tem # 4, então o shell vai fazer uma criança, fazer dup2(4,1) (lembre-se do meu cp exemplo?), e depois fazer execve() para realmente executar df. Naturalmente, df irá herdar o descritor de arquivo # 1, mas não saberá que ele não está mais apontando para o terminal, mas, na verdade, para o fd # 4, que é na verdade a extremidade de gravação do pipe. Naturalmente, a mesma coisa ocorrerá com grep 'foo' exceto com diferentes números de descritores de arquivos.

Agora, pergunta interessante: poderíamos fazer tubos que redirecionam fd # 2 também, não apenas fd # 1? Sim, na verdade é isso que |& faz em bash. O padrão POSIX requer linguagem de comando shell para suportar df 2>&1 | grep 'foo' sintaxe para esse propósito, mas bash faz |& também.

O que é importante notar é que os canais sempre lidam com descritores de arquivos. Existe FIFO ou tubo nomeado, que tem um nome de arquivo no disco e vamos usá-lo como um arquivo, mas se comporta como um pipe. Mas o | tipos de pipes são conhecidos como pipe anônimo - eles não têm nome de arquivo, porque são apenas dois objetos conectados juntos. O fato de não estarmos lidando com arquivos também implica uma implicação importante: canos não são lseek()'capaz. Arquivos, na memória ou no disco, são estáticos - programas podem usar lseek() syscall para pular para o byte 120, depois de volta para o byte 10, depois para frente até o final. Pipes não são estáticos - são sequenciais e, portanto, não é possível retroceder dados obtidos com eles lseek(). Isso é o que faz alguns programas saberem se estão lendo de arquivo ou de pipe e, portanto, podem fazer os ajustes necessários para um desempenho eficiente; em outras palavras, um prog pode detectar se eu faço cat file.txt | prog ou prog < input.txt. Exemplo de trabalho real do que é rabo.

As outras duas propriedades muito interessantes dos pipes são que elas têm um buffer, que no Linux é 4096 bytes, e eles realmente têm um sistema de arquivos conforme definido no código-fonte do Linux ! Eles não são simplesmente um objeto para passar dados, eles são uma própria estrutura de dados! Na verdade, porque existe sistema de arquivos pipefs, que gerencia tanto pipes quanto FIFOs, tubos têm um inode número em seus respectivos sistemas de arquivos:

# Stdout of ls is wired to pipe
$ ls -l /proc/self/fd/  | cat  
lrwx------ 1 user user 64 Sep 13 00:02 0 -> /dev/pts/0
l-wx------ 1 user user 64 Sep 13 00:02 1 -> pipe:[15655630]
lrwx------ 1 user user 64 Sep 13 00:02 2 -> /dev/pts/0
lr-x------ 1 user user 64 Sep 13 00:02 3 -> /proc/22/fd
# stdin of ls is wired to pipe
$ true | ls -l /proc/self/fd/0
lr-x------ 1 user user 64 Sep 13 03:58 /proc/self/fd/0 -> 'pipe:[54741]'

No Linux, os pipes são unidirecionais, assim como o redirecionamento. Em algumas implementações do tipo Unix - existem tubos bidirecionais. Embora com magia de scripts de shell, você pode fazer Canais bidirecionais no Linux também.

Veja também:


3
2017-09-12 09:26





Para adicionar às outras respostas, também há diferenças semânticas sutis - por exemplo, tubos fecham mais prontamente que os redirecionamentos:

seq 5 | (head -n1; head -n1)                # just 1
seq 5 > tmp5; (head -n1; head -n1) < tmp5   # 1 and 2
seq 5 | (read LINE; echo $LINE; head -n1)   # 1 and 2

No primeiro exemplo, quando a primeira chamada para head termina, fecha o tubo, e seq termina, então não há entrada disponível para o segundo head.

No segundo exemplo, a cabeça consome a primeira linha, mas quando fecha é própria stdin  tubo, o arquivo permanece aberto para a próxima chamada a ser usada.

O terceiro exemplo mostra que, se usarmos read para evitar o fechamento do pipe, ele ainda está disponível no subprocesso.

Portanto, o "fluxo" é a coisa pela qual nós derivamos os dados (stdin etc), e é o mesmo em ambos os casos, mas o canal conecta fluxos de dois processos, onde um redirecionamento conecta fluxos entre um processo e um arquivo. pode ver a fonte de ambas as semelhanças e diferenças.

P.S. Se você é tão curioso sobre e / ou surpreso por esses exemplos como eu estava, você pode se aprofundar ainda mais usando trap para ver como os processos são resolvidos, por exemplo:

(trap 'echo seq EXITed >&2' EXIT; seq 5) | (trap 'echo all done' EXIT; (trap 'echo first head exited' EXIT; head -n1)
echo '.'
(trap 'echo second head exited' EXIT; head -n1))

Às vezes o primeiro processo é fechado antes 1 é impresso, às vezes depois.

Eu também achei interessante usar exec <&- para fechar o fluxo do redirecionamento para aproximar o comportamento do pipe (embora com um erro):

seq 5 > tmp5
(trap 'echo all done' EXIT
(trap 'echo first head exited' EXIT; head -n1)
echo '.'
exec <&-
(trap 'echo second head exited' EXIT; head -n1)) < tmp5`

2
2018-06-05 00:54



"quando a primeira chamada à frente termina, fecha o tubo" Isso é realmente impreciso por dois motivos. Um, (head -n1; head -n1) é subshell com dois comandos, cada um dos quais herda o fim de leitura do pipe como descritor 0, e assim subshell E cada comando tem esse descritor de arquivo aberto. Segunda razão, você pode ver isso com strace -f bash -c 'seq 5 | (head -n1; head -n1) '. Então, primeiro chefe fecha apenas sua cópia do descritor de arquivo - Sergiy Kolodyazhnyy
O terceiro exemplo também é impreciso, porque read consome apenas a primeira linha (isso é um byte para 1 e nova linha). seq enviado no total de 10 bytes (5 números e 5 novas linhas). Então, há 8 bytes restantes no buffer de tubulação, e é por isso que o segundo head funciona - há dados ainda disponíveis no buffer de tubulação. Btw, cabeça sai apenas se houver 0 bytes lidos, como em head /dev/null - Sergiy Kolodyazhnyy
Obrigado pelo esclarecimento. Estou entendendo corretamente que em seq 5 | (head -n1; head -n1) a primeira chamada esvazia o pipe, então ela ainda existe em um estado aberto, mas sem dados para a segunda chamada. head? Portanto, a diferença de comportamento entre o pipe e o redirecionamento é porque o head extrai todos os dados do pipe, mas apenas as duas linhas do manipulador de arquivos? - Julian de Bhal
Está correto. E é algo que pode ser visto com strace comando eu dei no primeiro comentário. Com o redirecionamento, o arquivo tmp está no disco, o que o torna pesquisável (porque eles usam lseek() syscall - os comandos podem pular o arquivo do primeiro byte para o último, da maneira que quiserem. Mas os tubos são sequenciais e não são procuráveis. Então, a única maneira de o chefe fazer o seu trabalho é ler tudo primeiro, ou se o arquivo é grande - mapeie um pouco para a RAM via mmap() ligar. Uma vez fiz o meu próprio tail em Python, e se deparou com exatamente o mesmo problema. - Sergiy Kolodyazhnyy
Também é importante lembrar que o fim de leitura do pipe (descritor de arquivo) é dado ao subshell primeiro (...), e o subshell fará a cópia de seu próprio stdin para cada comando dentro (...). Então, eles são tecnicamente lidos do mesmo objeto. Primeiro head  acha que está lendo de seu próprio stdin. Segundo head acha que tem seu próprio stdin. Mas, na realidade, o fd # 1 (stdin) é apenas uma cópia do mesmo fd, que é o final do canal. Além disso, eu postei uma resposta, então talvez ajude a esclarecer as coisas. - Sergiy Kolodyazhnyy


Eu tenho um problema com isso em C hoje. Essencialmente, o Pipe tem semânticas diferentes para redirecionamentos, mesmo quando enviados para stdin. Realmente acho que, dadas as diferenças, os tubos devem ir para outro lugar que não stdin, de modo a stdin e vamos chamá-lo stdpipe (para fazer um diferencial arbitrário) pode ser tratado de maneiras diferentes.

Considere isto. Quando canalizar uma saída de programa para outra fstat parece retornar zero como o st_size apesar ls -lha /proc/{PID}/fd mostrando que existe um arquivo. Ao redirecionar um arquivo, este não é o caso (pelo menos no debian wheezy, stretch e jessie baunilha e ubuntu 14.04, 16.04 baunilha.

Se vocês cat /proc/{PID}/fd/0 Com um redirecionamento, você poderá repetir a leitura quantas vezes quiser. Se você fizer isso com um pipe, notará que na segunda vez que executar a tarefa consecutivamente, você não obterá a mesma saída.


1
2017-10-26 16:17