Entrada padrão múltipla? Quão?

36

Nesta linha de comando, você deve postar :

$ diff <(wget -q -O - URL1) <(wget -q -O - URL2)

Parece várias entradas padrão, mas --- se eu me lembro corretamente do meu curso de Porgramming do Linux --- não pode ser isso. Eu pensei que, por definição, a entrada padrão era um fluxo.

Talvez isso tenha a ver com stdin? Alguém pode me explicar isso; talvez forneça links para a documentação.

Bônus: como um script lidaria com esses múltiplos fluxos? Se alguém pudesse fornecer um exemplo de Python ou Perl, isso seria muito útil.

Belmin Fernandez
fonte
11
Boa pergunta. Caso você não saiba
Matt Ellen
2
Documentação para substituições de processo: gnu.org/software/bash/manual/bashref.html#Process-Substitution
Glenn Jackman
Nota: no Bash é <(…); na sintaxe de substituição do processo Zsh é =(…).
Kamil Maciorowski

Respostas:

27

Esta não é uma entrada padrão múltipla. Este é um bash'ism chamado "Substituição de Processo" http://tldp.org/LDP/abs/html/process-sub.html

Ele cria um pseudo arquivo ( /dev/fd/something) para cada substituição. É bem útil. O comando pode ler apenas como um fluxo, o que significa que não pode ir e voltar com o fseek. Ele precisa lê-lo como um fluxo de bytes, como um tubo.

Resposta BÔNUS

Você não precisa fazer muito para usar isso. No que diz respeito ao seu script, ele obtém um nome de arquivo válido na linha de comando, que pode ser aberto () como qualquer outra coisa. Como outros já disseram, você veria diff /dev/fd/XX /dev/fd/YY. Se você fizer um stat () em qualquer um desses pseudo-arquivos, verá que é um pipe nomeado e deve tratá-lo com semântica de pipe - ou seja, sem fseek () ou ftell (). Se você fizer um teste stat () para ver explicitamente se é um arquivo (por exemplo [ -f $1 ]), isso será interrompido - afinal, ele é implementado como um pipe nomeado.

Rich Homolka
fonte
Outra boa referência para substituição processo Bash - wiki.bash-hackers.org/syntax/expansion/proc_subst
studgeek
E qual é o uso recomendado desse recurso? Ofereça suporte sempre que seu programa puder funcionar razoavelmente com um fluxo em vez de exigir um arquivo com acesso aleatório?
masterxilo 15/04
7

<(...)faz substituição processo em bash. A saída do processo no parens é enviada para um descritor de arquivo adicional além do normal 3 e um nome de arquivo é retornado correspondente ao descritor de arquivo. Dessa maneira, a saída de um comando pode ser tratada como um nome de arquivo a ser passado para outro comando.

Ignacio Vazquez-Abrams
fonte
7

Há um stdine um stdout para cada processo . Eles geralmente estão conectados ao terminal, mas podem ser redirecionados separadamente um do outro.

No exemplo, há dois wgetprocessos envolvidos, cada um com seu próprio valor stdine stdout. Cada wgetprocesso grava em -, qual é o seu stdout. Então bash's substituição processo de <(...)liga o stdoutdo processo a um pseudo-arquivo único, a partir do qualdiff possível ler. Observe que as duas substituições de processo produzem dois pseudo-arquivos diferentes! Assim, diffvê algo como:

diff /dev/fd/XX /dev/fd/YY

onde o stdoutde wget -q -O - URL1está conectado /dev/fd/XXe o stdoutde wget -q -O - URL2para /dev/fd/YY.

musiphil
fonte