Linux
為什麼 BASH 程序替換不適用於某些命令?
有時程序替換不會按預期工作。這是一個例子:
輸入:
gcc <(echo 'int main(){return 0;}')
輸出:
/dev/fd/63: file not recognized: Illegal seek collect2: error: ld returned 1 exit status
輸入:
但是當與不同的命令一起使用時,它會按預期工作:
grep main <(echo 'int main(){return 0;}')
輸出:
int main(){return 0;}
我注意到其他命令也出現了類似的故障(即,從程序替換中期望文件的命令不能使用
/dev/fd/63
或類似的命令)。這次失敗gcc
只是最近的一次。是否有一些我應該知道的一般規則來確定程序替換何時會以這種方式失敗並且不應該使用?我在 Ubuntu 12.04 上使用這個 BASH 版本(我也在 arch 和 debian 中看到過這個):
GNU bash,版本 4.3.11(1)-release (i686-pc-linux-gnu)
程序替換會生成一個特殊文件(如
/dev/fd/63
您的範例中),其行為類似於命名管道的讀取端。該文件可以打開和讀取,但不能寫入,不能查找。將其參數視為純流的命令起作用,而期望在給定文件中查找(或寫入文件)的命令將不起作用。可以使用的命令類型通常被認為是過濾器:
cat
,grep
,sed
,gzip
, ,awk
等等vi
……mv
gcc
希望能夠對其輸入文件執行隨機訪問,以檢測它們是用什麼語言編寫的。如果您改為gcc
提示輸入文件的語言,它很樂意流式傳輸文件:gcc -x c <(echo 'int main(){return 0;}')
沒有程序替換的更簡單更直接的形式也適用:
echo 'int main(){return 0;}' | gcc -x c -
請注意,這不是特定於
bash
. 所有支持程序替換的 shell 的行為方式都相同。