Entrada múltipla padrão? Como?

31

A partir deste post de commandline :

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

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

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

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

    
por Belmin Fernandez 21.10.2010 / 00:53

3 respostas

24

Esta não é uma entrada múltipla padrão. Este é um bash'ism que chamou 'Substituição de Processo'    link

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

Resposta do BONUS

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 disseram, você veria diff /dev/fd/XX /dev/fd/YY . Se você fizer um stat () em qualquer um desses pseudo-arquivos, você verá que é um pipe nomeado, e você 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á quebrado - isso é implementado como um pipe nomeado depois de tudo.

    
por 21.10.2010 / 01:08
7

<(...) faz substituição de processo no bash. A saída do processo nos parênteses é enviada para um descritor de arquivo adicional além do normal 3, e um nome de arquivo é retornado correspondendo a esse descritor de arquivo. Desta forma, a saída de um comando pode ser tratada como um nome de arquivo para ser passado para outro comando.

    
por 21.10.2010 / 01:08
6

Existe um stdin e um stdout para cada processo . Eles geralmente estão conectados ao terminal, mas podem ser redirecionados separadamente um do outro.

No exemplo, há dois wget processos envolvidos, cada um com seus próprios stdin e stdout . Cada processo de wget grava em - , que é seu stdout . Em seguida, a substituição do processo bash <(...) conecta o stdout do processo a um pseudo arquivo exclusivo, do qual diff pode ler. Note que as duas substituições de processo geram dois pseudo-arquivos diferentes! Assim, diff vê algo como:

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

em que stdout de wget -q -O - URL1 está conectado a /dev/fd/XX e stdout de wget -q -O - URL2 a /dev/fd/YY .

    
por 02.06.2012 / 01:47