Pipe執行
執行 cat | 時我不理解
cat 的行為ls
我知道這是一個無用的命令,但我想了解為什麼,無論是在
bash
還是zsh
,當我輸入時cat | ls
,cat
會提示我輸入,但只會在一行之後返回,而例如</dev/stdin tr -d 'e' | ls
讓我輸入多行直到我點擊Ctrl + D
?
這與僅在 1 秒後列印任何內容的原因相同:
(echo abc; sleep 1; echo def) | tr -d e |cat
將標準輸出重定向到管道後,大多數實用程序開始緩衝輸出,並且只有在它們擁有完整的數據塊後才在那裡寫入任何內容。(塊的大小是一個實現細節,它可能是幾千字節。)您可以使用一些實用程序來禁用緩衝,請參閱:關閉管道中的緩衝。
但是有些實現
cat
不做緩衝,而是立即寫入。這至少包括 GNU 和 Busybox 實現。POSIX 沒有指定plaincat
對緩衝的作用,只是為了防止緩衝。cat -u
在這裡,由於
ls
沒有從標準輸入讀取任何內容,因此也不會從管道中讀取任何內容,因此它可能比您鍵入任何內容都更快地完成和退出。因此,當cat
/tr
開始寫任何東西時,管道已經關閉,並且 writer 得到一個 SIGPIPE 並退出。由於cat
這裡會立即寫入它讀取的內容而無需緩衝,因此它會在第一條輸入行之後立即獲取信號。另一方面,由於tr
等待獲得一個完整的緩衝區來寫入任何內容,因此第一行輸入不會觸發它。如果輸入了足夠多的數據,tr
最終也會將其寫入管道,獲取信號並退出。就像你說的,管道
ls
是愚蠢的,因為它不讀取任何內容。你可以使用類似true
或false
代替的東西。