Ocasionalmente, a substituição do processo não funcionará conforme o esperado. Aqui está um exemplo:
Entrada:
gcc <(echo 'int main(){return 0;}')
Saída:
/dev/fd/63: file not recognized: Illegal seek
collect2: error: ld returned 1 exit status
Entrada:
Mas funciona como esperado quando usado com um comando diferente:
grep main <(echo 'int main(){return 0;}')
Saída:
int main(){return 0;}
Eu notei falhas semelhantes com outros comandos (ou seja, o comando que espera o arquivo da substituição do processo não pode usar /dev/fd/63
ou semelhante). Essa falha gcc
é apenas a mais recente. Existe alguma regra geral que eu deva conhecer para determinar quando a substituição do processo falhará dessa maneira e não deve ser usada?
Estou usando esta versão BASH no Ubuntu 12.04 (também vi isso no arch e no debian):
GNU bash, versão 4.3.11 (1) -release (i686-pc-linux-gnu)
illegal seek
parece a resposta - a|pipe
quebash
aponta o programa executado não é um arquivo procurável. Provavelmente, se você não conseguir obter êxitoecho data | command /dev/fd/0
em um programa, terá sorte semelhante com<(cmd)
. Ele não fornece um arquivo em disco - apenas substitui um argumento que aponta para um descritor de arquivo pipe.gcc -xc <(echo 'int main(){return 0;}')
(que define o idiomaC
explicitamente).Respostas:
A substituição do processo resulta em um arquivo especial (como
/dev/fd/63
no seu exemplo) que se comporta como o final de leitura de um pipe nomeado. Este arquivo pode ser aberto e lido, mas não gravado, não procurado.Comandos que tratam seus argumentos como fluxos puros funcionam, enquanto comandos que esperam buscar nos arquivos que recebem (ou gravá-los) não funcionam. O tipo de comando que vai funcionar é o que é geralmente considerado um filtro:
cat
,grep
,sed
,gzip
,awk
, etc ... Um exemplo de um comando que não vai funcionar é um editor comovi
ou uma operação de arquivo comomv
.gcc
deseja poder executar acesso aleatório em seus arquivos de entrada para detectar em qual idioma eles estão escritos. Se você dergcc
uma dica sobre o idioma do arquivo de entrada, será um prazer transmitir o arquivo:A forma mais simples e direta, sem substituição de processo, também funciona:
Observe que isso não é específico para
bash
. Todos os shells que suportam a substituição de processos se comportam da mesma maneira.fonte
<()
formato deve funcionar como um arquivo para todos os efeitos. Na verdade, não conheço nenhum comando que espere um arquivo que não seja feliz<()
. Os que não funcionam são aqueles que esperam nomes de arquivos , não arquivos. Por exemplo,grep -f
espera um arquivo e funciona bem<()
.<()
produz um nome de arquivo (a construção se expande/proc/self/fd/something
no meu sistema). Esse nome, quando aberto, atua como o final de leitura de um pipe nomeado (S_IFIFO
), em vez de um arquivo comum (S_IFREG
), em suportesread()
e outros, mas nãoseek()
.zsh
suporta uma terceira forma de substituição processo que utiliza arquivos temporários, especialmente para o efeito:gcc =(echo 'int main(){return 0;}')
<(echo '...')
mas não com<(git show ...)
. Alguma idéia do porquê disso?ld
(que detecta os formatos dos objetos).-x
não é uma dica; é uma declaração. Se você especificar-x f95
, o GCC passará o arquivo para o compilador Fortran-95, independentemente de seu nome ou conteúdo. Veja gcc.gnu.org/onlinedocs/gcc-8.1.0/gcc/Overall-Options.html