Náhrada procesu někdy nebude fungovat podle očekávání. Zde je příklad:
Vstup:
gcc <(echo 'int main(){return 0;}')
Výstup:
/dev/fd/63: file not recognized: Illegal seek
collect2: error: ld returned 1 exit status
Vstup:
Při použití s jiným příkazem to však funguje podle očekávání:
grep main <(echo 'int main(){return 0;}')
Výstup:
int main(){return 0;}
Všiml jsem si podobných selhání u jiných příkazů (tj. příkaz, který očekává soubor ze substituce procesu, nemůže použít /dev/fd/63
nebo podobné). Tato chyba s gcc
je jen nejnovější. Existuje nějaké obecné pravidlo, kterého bych si měl být vědom, abych určil, kdy substituce procesu tímto způsobem selže a neměla by se používat?
Používám tuto verzi BASH na Ubuntu 12.04 (také jsem to viděl v archu a debianu):
GNU bash, verze 4.3.11(1)-release (i686-pc-linux-gnu)
Přijatá odpověď:
Výsledkem nahrazení procesu je speciální soubor (jako /dev/fd/63
ve vašem příkladu), který se chová jako čtecí konec pojmenovaného kanálu. Tento soubor lze otevřít a číst, ale nelze jej zapisovat, nelze jej vyhledávat.
Příkazy, které zacházejí se svými argumenty jako s čistými datovými proudy, fungují, zatímco příkazy, které očekávají, že budou vyhledávat v souborech, které jim jsou zadány (nebo do nich zapisovat), nebudou fungovat. Typ příkazu, který bude fungovat, je obvykle považován za filtr:cat
, grep
, sed
, gzip
, awk
, atd... Příkladem příkazu, který nebude fungovat, je editor jako vi
nebo operace se souborem jako mv
.
gcc
chce mít možnost provádět náhodný přístup ke svým vstupním souborům, aby zjistil, v jakém jazyce jsou napsány. Pokud místo toho zadáte gcc
nápovědu k jazyku vstupního souboru, je potěšením soubor streamovat:
gcc -x c <(echo 'int main(){return 0;}')
Funguje také jednodušší a přímočařejší forma bez substituce procesu:
echo 'int main(){return 0;}' | gcc -x c -
Všimněte si, že to není specifické pro bash
. Všechny shelly, které podporují substituci procesů, se chovají stejně.