Linux
什麼控制 stdout stderr 的緩衝?
當程序啟動時,系統的哪一部分設置了三個標準流的緩衝?
這是 linux 的一部分,還是 glibc,或者可能是 bash?POSIX 是否定義了行為,或者它是 C 的一部分?
Posix 有一些答案:
https://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_05
在程序啟動時,三個流是預定義的,不需要顯式打開:標準輸入(用於讀取正常輸入)、標準輸出(用於寫入正常輸出)和標準錯誤(用於寫入診斷輸出)。打開時,標準錯誤流沒有完全緩衝;當且僅當可以確定流不引用互動式設備時,標準輸入和標準輸出流才被完全緩衝。
因此,如果系統可以確定流不是互動式的,則它們可以被完全緩衝(stderr 除外),但實際上這確定了系統的哪個部分?
你的程式語言
這種行為是 C 執行時庫的產物,也是 C 程式語言的要求。歷史上,其他程式語言都建立在 C 執行時庫之上,並從中獲得這種行為。例如,對於 C++ 程序就是如此。Stack Overflow (qv) 上經常引用 C 和 C++ 語言標準的章節和經文。
最值得注意的是,用 Python 編寫的程序具有相同的行為,並且經常被問及,有時會歸咎於程式語言執行時的行為被嚴重錯誤放置。
改變使用預設語言語義(無需修改和重新編譯程序)的程序的這種行為的工具有兩種形式:依賴於語言(有時是特定於執行時庫)的工具,它們將自身插入執行時並更改緩衝,以及將標準 I/O 製作成執行時庫決定為互動式設備的文件的工具。後一類中的工具與語言無關,包括 Bernstein
ptybandage
。進一步閱讀
- https://unix.stackexchange.com/a/407472/5132
- https://unix.stackexchange.com/a/249801/5132
- http://git.musl-libc.org/cgit/musl/tree/src/stdio/__stdout_write.c#n8
只是緩衝問題的幾個例子: