デフォルトのstdoutバッファはどのように設定されますか?

デフォルトのstdoutバッファはどのように設定されますか?

Red Hat EL7で実行すると、ログファイルにこのような長い行があり、次のようになりました。

tail -f Log | cut -c1-$COLUMNS

これは一部のシステムではうまく機能しますが、他の(明らかに同じ)システムでは、バッファがいっぱいになるまでパイプはデータを保持します。私がこれを入力している間、SEは私にこれ使用時の回答:

tail -f Log | stdbuf -oL cut -c1-$COLUMNS

私は必要なことを行いますが、違いが何であるかを知りたいです。私はシステムが良いか悪いか同じように実行したいと思います。

デフォルトのバッファリングが設定されていますか?どのように、どこに設定されていますか?

更新:問題のあるシステムで2つのウィンドウを開こうとしました。

while date; do usleep 500000 ; done | cut -c1-100

出力がありません(バッファがいっぱいになるまで)。別のウィンドウでクリッピングプロセスに対してstraceを実行しましたが、無限の一連のメッセージを受け取りました。

read(0, "Wed Oct 26 13:04:12 CDT 2022\n", 4096) = 29
read(0, "Wed Oct 26 13:04:12 CDT 2022\n", 4096) = 29
read(0, "Wed Oct 26 13:04:13 CDT 2022\n", 4096) = 29
read(0, "Wed Oct 26 13:04:13 CDT 2022\n", 4096) = 29
read(0, "Wed Oct 26 13:04:14 CDT 2022\n", 4096) = 29
read(0, "Wed Oct 26 13:04:14 CDT 2022\n", 4096) = 29
read(0, "Wed Oct 26 13:04:15 CDT 2022\n", 4096) = 29

私はそれがカットが緩衝効果を持っているというかなり確実な証拠だと思います。しかし、どうやってこれを行うことにしましたか?

答え1

一般的な動作は、端末への出力がラインバッファリングされ、他のすべての出力がブロックバッファリングされることです。たとえば、参照してください。GNU glibc マニュアル:

新しく開かれたストリームは通常完全にバッファリングされますが、1つの例外は、対話型デバイス(端末など)に接続されたストリームが最初にラインバッファリングされることです。 [...]

そのように

grep ... | cut ...

ありますgrep出力はバッファリングされますが、バッファリングされません。 (または)を実行してこの問題を解決cutできます。または他の多くの回避策のいずれかを使用してください。以下を参照してください。stdbuf -o0 grep ...grep --line-bufferedパイプラインでバッファリングをオフにする

一方、対応tail -fする出力はバッファリングしてはいけません。

stdbuf -oLもちろん、これは使用について述べたものと一致しません。cut修正してください。すでに出力をラインバッファリングする必要があります。ターミナルに行けばそうですね。あったら| cut ... > somefile違いました。

関連情報