ディレクトリをtar
して結果をstdout
に書き込み、それを次のように圧縮プログラムにパイプします。
tar -cvf - /tmp/source-dir | lzip -o /media/my-usb/result.lz -
数行のテキストを出力するコマンドでパイプをずっと使用しています。 tar
のような非常に大きな出力を持つ(高速)コマンドをパイプ処理し、その後に非常に遅い圧縮コマンドを実行するとどうなるのでしょうか。 tar
は、その出力がlzip
によって消費されるのを待ちますか?それとも、すべてをRAMに出力できるのと同じくらい高速に動作しますか?後者が本当なら、低システムでの惨事になるRAM=システム。
データプロデューサー(tar
)がコンシューマー(lzip
)がすべてを読み取る時間を確保できないほど速くパイプに書き込もうとすると、lzip
がtar
が書き込んでいる内容を読み取る時間がなくなるまでブロックされます。パイプに関連付けられた小さなバッファーがありますが、そのサイズはほとんどのtar
アーカイブのサイズよりも小さい可能性があります。
「ブロッキング」とは単に、tar
がwrite()
ライブラリ関数(または同等の関数)を呼び出したときに、データがパイプバッファーに送信されるまで呼び出しが返されないことを意味します。 lzip
が同じバッファーからの読み取りに時間がかかる場合の時間。これをtop
で確認できるはずです。tar
は、lzip
と比較して速度が低下し、多くの時間スリープします(tar
は実際にはlzip
より速いと想定しています)。
したがって、notパイプラインでRAMのかなりの量を埋めます。これを行うには(必要に応じて)、中央にpv
のようなものを使用できます、いくつかのバッファ付き:
_tar -cvf - /tmp/source-dir | pv --buffer-size 1G | lzip -o /media/my-usb/result.lz -
_
これにより、tar
がブロックするたびにpv
がブロックされます。 pv
は、バッファがいっぱいになり、lzip
に書き込めない場合にブロックします。
逆の状況も同様に機能します。つまり、パイプの左側が遅く右側が高速である場合、右側のコンシューマーはデータがあるまでread()
をブロックしますパイプから読み取られる。
これ(データI/O)は、パイプラインに参加するプロセスを同期する唯一のものです。読み取りと書き込み(および他の誰かが読み取りまたは書き込みを行うのを待つ間、時々ブロックする)を除いて、それらは互いに独立して実行されます。
GNU tarには-lzipへの-lzipオプションがあるため、代わりに使用することができます。
tar -cvf --lzip /media/my-usb/result.lz /tmp/source-dir
質問への回答:あなたの場合、システムはデフォルトのシステムバッファーサイズを使用してパイプを適切に管理します。