Pipe

執行 cat | 時我不理解 cat 的行為ls

  • October 22, 2021

我知道這是一個無用的命令,但我想了解為什麼,無論是在bash還是zsh,當我輸入時cat | lscat會提示我輸入,但只會在一行之後返回,而例如</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是愚蠢的,因為它不讀取任何內容。你可以使用類似truefalse代替的東西。

引用自:https://unix.stackexchange.com/questions/673855