Por que o processo de substituição resulta em um arquivo chamado / dev / fd / 63 que é um pipe?

34

Estou tentando entender os pipes nomeados no contexto desse exemplo específico.

Eu digito <(ls -l) no meu terminal e obtenho a saída como bash: /dev/fd/63: Permission denied .

Se eu digitar cat <(ls -l) , eu poderia ver o conteúdo do diretório. Se eu substituir o cat por echo , acho que recebo o nome do terminal (ou é?).

echo <(ls -l) fornece a saída como /dev/fd/63 .

Além disso, este exemplo de saída não está claro para mim.

ls -l <(echo "Whatever")
lr-x------ 1 root root 64 Sep 17 13:18 /dev/fd/63 -> pipe:[48078752]

No entanto, se eu der, ls -l <() me lista o conteúdo do diretório.

O que está acontecendo no caso do pipe nomeado?

    
por Ramesh 17.09.2014 / 20:17

2 respostas

33

Quando você executa <(some_command) , seu shell executa o comando dentro dos parênteses e substitui tudo com um descritor de arquivo, que está conectado ao stdout do comando. Então /dev/fd/63 é um pipe contendo a saída da sua chamada ls.

Quando você executa <(ls -l) , recebe um erro Permission denied , porque a linha inteira é substituída pelo pipe, tentando efetivamente chamar /dev/fd/63 como um comando, que não é executável.

No seu segundo exemplo, cat <(ls -l) se torna cat /dev/fd/63 . Como gato lê os arquivos dados como parâmetros você obtém o conteúdo. Por outro lado, echo apenas exibe seus parâmetros "como estão".

O último caso que você tem, <() é simplesmente substituído por nada, pois não há comando. Mas isso não é consistente entre shells, em zsh você ainda pega um pipe (embora vazio).

Resumo : <(command) permite usar a saída de um comando, onde você normalmente precisaria de um arquivo.

Edit: como Gilles aponta, este não é um pipe nomeado, mas um tubo anônimo. A principal diferença é que ela existe apenas, desde que o processo esteja em execução, enquanto um pipe nomeado (criado, por exemplo, com mkfifo ) permanecerá sem processos anexados a ele.

    
por 17.09.2014 / 20:50
-5

Você entendeu mal o comando ls e o redirecionamento. ls lista os arquivos e diretórios dados na linha de comando, não acredito que aceite nenhuma entrada de stdin. Redirecionamento > >> e < são maneiras de usar um arquivo para fornecer entrada e coletar a saída.

    
por 17.09.2014 / 20:57