Dois tubos para um comando

9

Estou um pouco confuso com a seguinte sintaxe. Embora funcione, ele não entende por que funciona. Parece que existem dois tubos conectados ao comando diff. Mas não há apenas um STDIN?

Exemplos:

diff <(echo "foobar") <(echo "barbaz")
diff <(cat foo.txt) <(cat bar.txt)
iblue
fonte
Aqui está um link para o tópico relevante - substituição de processo - na bashpágina de manual.
chepner

Respostas:

13

Os pipes são simplesmente vinculados a descritores de arquivos diferentes de 0 (stdin):

$ echo <(true)
/dev/fd/63
$ echo <(true) <(true)
/dev/fd/63 /dev/fd/62

É claro que um processo pode ter mais de um descritor de arquivo aberto por vez, portanto não há problema.

Sven Marnach
fonte
Se eu soubesse os chamados tubos temporários, eu poderia pesquisar no Google. Obrigado!
@iblue: Eu não acho que se chame "tubos temporários". São apenas tubos, criados pela pipe()chamada do sistema.
Sven Marnach 8/12
Para ser muito exato, pode ser chamado de "pipes nomeados anônimos", mas é suficiente para pesquisar no Google.
2
@WilliamPursell: Não há arquivos envolvidos. O shell cria um canal anônimo usando pipe()e bifurca os subprocessos. O processo principal não têm descritores de arquivos adicionais aberto se um pipe anônimo é usado. Esses descritores de arquivos adicionais são passados ​​no formulário /dev/fd/...e o processo geralmente os abre usando esses nomes de arquivos. Isso fará com que sejam dup()editados, criando ainda mais descritores de arquivos abertos. O processo também pode usar o descritor de arquivo chamado imediatamente, sem quaisquer chamadas abertas ...
Sven Marnach
11
... como demonstrado neste programa de teste pequeno e estúpido . Depois de compilar a, chamei-o como ./a <(ls), e ele imprimiu com êxito a lista de arquivos, provando que o descritor de arquivo nomeado (63 no meu caso) já estava aberto. O bash pode usar pipes nomeados em um diretório temporário em arquiteturas diferentes do Linux; nesse caso, nenhum descritor de arquivo adicional seria aberto ao entrar no processo principal.
Sven Marnach 8/12