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.