tar
ディレクトリをインポートして結果を作成し、stdout
次のようにコンプレッサにパイプしたいと思います。
tar -cvf - /tmp/source-dir | lzip -o /media/my-usb/result.lz -
私は複数行のテキストを含むコマンドを出力するためにパイプを使用してきました。今、非常に大きな出力(例えば、tar
非常に遅い圧縮命令の後に続く)を含む(高速)命令をパイプするとどうなりますか?tar
出力が消費されるのを待ちますかlzip
?それとも、できるだけ早くすべてをRAMに出力しますか?後者が真であれば、RAMが少ないシステムでは災害になります。
答え1
データプロデューサ(tar
)がパイプに書きすぎようとして消費者(lzip
)がすべてのデータを読み取る時間がない場合詰まった書かれた内容をlzip
読む時間があるまで。tar
パイプに関連する小さなバッファがありますが、そのサイズはおそらくtar
ほとんどのアーカイブより小さいでしょう。パイプがシステムRAMを満たす危険はありません。
「ブロック」は、単にtar
ライブラリ関数(またはそれに対応する関数)が呼び出されたときにデータがパイプバッファに渡されるまで呼び出しが返されないことを意味し、同じバッファからの読み込みが遅い場合は時間がかかることがありwrite()
ます。lzip
(実際にはより速いと仮定すると)スピードが遅くなり、睡眠の多い場所と比べるとこれを見るtop
ことができます。tar
lzip
tar
lzip
だからあなたはいいえ大量の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)パイプに参加しているプロセスを同期する唯一のものです。読取りと書込み(他の人が読んだり書くのを待っているときに時々ブロックされる)を除いて、互いに独立して実行されます。
答え2
牛に似た一種の栄養アスファルト持つ--lzipオプション「lzipによるアーカイブのフィルタリングそのため、次のように使用することもできます。
tar -cvf --lzip /media/my-usb/result.lz /tmp/source-dir
質問に答えてください。あなたの場合、システムはデフォルトのシステムバッファサイズを使用してパイプを正しく管理します。