Shell
流程替換和管道
我想知道如何理解以下內容:
將命令的標準輸出通過管道傳輸到另一個命令的標準輸入是一種強大的技術。但是,如果您需要通過管道傳輸多個命令的標準輸出怎麼辦?這就是流程替換的用武之地。
換句話說,程序替換可以做任何管道可以做的事情嗎?
程序替換可以做什麼,但管道不能?
了解它們之間差異的一個好方法是在命令行上做一些實驗。儘管在使用
<
字元時在視覺上很相似,但它的作用與重定向或管道非常不同。讓我們使用該
date
命令進行測試。$ date | cat Thu Jul 21 12:39:18 EEST 2011
這是一個毫無意義的範例,但它表明
cat
接受了date
STDIN 上的輸出並將其吐回。通過程序替換可以實現相同的結果:$ cat <(date) Thu Jul 21 12:40:53 EEST 2011
然而,剛剛發生在幕後的事情卻有所不同。實際上,它並沒有得到一個 STDIN 流,而是
cat
傳遞了它需要打開和讀取的文件的名稱。您可以通過使用echo
而不是來查看此步驟cat
。$ echo <(date) /proc/self/fd/11
當 cat 收到文件名時,它會為我們讀取文件的內容。另一方面,echo 只是向我們顯示了它傳遞的文件名。如果添加更多替換,這種差異會變得更加明顯:
$ cat <(date) <(date) <(date) Thu Jul 21 12:44:45 EEST 2011 Thu Jul 21 12:44:45 EEST 2011 Thu Jul 21 12:44:45 EEST 2011 $ echo <(date) <(date) <(date) /proc/self/fd/11 /proc/self/fd/12 /proc/self/fd/13
可以將程序替換(生成文件)和輸入重定向(將文件連接到 STDIN)結合起來:
$ cat < <(date) Thu Jul 21 12:46:22 EEST 2011
它看起來幾乎相同,但這次 cat 傳遞的是 STDIN 流而不是文件名。您可以通過使用 echo 來查看:
$ echo < <(date) <blank>
由於 echo 不讀取 STDIN 並且沒有傳遞任何參數,所以我們什麼也得不到。
管道和輸入重定向將內容推送到 STDIN 流上。程序替換執行命令,將它們的輸出保存到一個特殊的臨時文件,然後傳遞該文件名來代替命令。無論您使用什麼命令,都將其視為文件名。請注意,創建的文件不是正常文件,而是一個命名管道,一旦不再需要它就會自動刪除。