Bash 如何管道大量數據?
假設您想對一個非常大的文件的內容進行分類,但想一次查看幾位。假設一個人要執行以下操作:
$ cat /dev/sda1 | less
作為 Java 和 ActionScript 等語言的程序員,當我查看該程式碼時,我想像 Bash 首先執行命令(將命令返回的所有內容
cat /dev/sda1
載入到 RAM 中),然後執行可以訪問那個非常大的“偽變數”的命令"表示為。less``-
是 Bash 做事的方式嗎(這意味著如果文件大於系統上的 RAM 量,則該命令是一個非常糟糕的主意,您應該使用另一個命令),還是它有一種優化大型管道的方法?數據量?
不,它不會將所有內容都載入到記憶體中,這將是一種不切實際的設計方式。它使用緩衝區來緩衝管道左側的輸出,然後將這些緩衝區連接到管道右側命令的輸入。
手冊頁
man 7 pipe
包含所有詳細資訊,以及標題為:管道緩衝區有多大?
read 將阻塞直到數據可用,而 write 將阻塞或失敗,以防管道已滿。PIPE_BUF、PIPE_SIZE和O_NONBLOCK等參數很少在管道中起關鍵作用。
PIPE_BUF 的值可以通過 ‘ulimit -a’ 確定。它在limits.h中定義。PIPE_BUF 控制atomic write的保證大小。這有助於製作安全的多執行緒應用程序。
PIPE_SIZE 取決於頁面大小。在 2.4 核心中,它相當於一頁(4KB)的大小。但是 2.6 之後的版本映射到 16 頁 (64KB) 的數組。這在文件 pipe_fs_i.h 中定義為 PIPE_BUFFERS (16)。更高版本的核心具有 fcntl 和 F_SETPIPE_SZ 啟用增加頁面大小。
O_NONBLOCK 可以執行部分寫入和延遲寫入。但是,如果啟用了 O_NONBLOCK,但如果要寫入管道的字節數大於 PIPE_BUF,則如果管道已滿,則寫入將失敗,否則根據 write 的返回值,它將與來自其他程序的數據交錯.