本当に大きいファイルの内容を猫にしたいが、一度に数ビットずつ表示したいとします。次のことを行うとしましょう。
$ cat /dev/sda1 | less
JavaやActionScriptなどの言語のプログラマーとして、そのコードを見ると、Bashが最初にコマンドcat /dev/sda1
(loading everything the command RAMに戻ります)、次にコマンドless
を実行します。このコマンドは、-
として表される非常に大きな「疑似変数」にアクセスできます。
それはBashが物事を行う方法です(つまり、ファイルがシステム上のRAM)の量よりも大きい場合、コマンドは本当に悪いアイデアであり、使用する必要があります)別のコマンド)、または大量のデータのパイピングを最適化する方法がありますか?
いいえ、すべてをメモリにロードするわけではありません。これを設計するのは非現実的な方法です。バッファを使用してパイプの左側からの出力をバッファリングし、次にこれらのバッファをパイプの右側のコマンドの入力に接続します。
マニュアルページman 7 pipe
には、すべての詳細と、次のタイトルのこの他のU&L Q&Aがあります。 パイプバッファの大きさは?
読み取りはデータが利用可能になるまでブロックし、書き込みはパイプがいっぱいになるとブロックまたは失敗します。 PIPE_BUF、PIPE_SIZE、O_NONBLOCKなど、パイプで重要な役割を果たすパラメーターはほとんどありません。
PIPE_BUFの値は、「ulimit-a」を介して決定できます。これはlimits.hで定義されています。 PIPE_BUFは、アトミック書き込みの保証サイズを制御します。これは、安全なマルチスレッドアプリの作成に役立ちます。
PIPE_SIZEは、ページサイズによって異なります。 2.4カーネルでは、1ページ(4KB)のサイズに相当します。ただし、2.6以降のバージョンは、16ページ(64KB)の配列にマップされます。これは、ファイルpipe_fs_i.hでPIPE_BUFFERS(16)として定義されています。それ以降のバージョンのカーネルには、ページサイズの増加を可能にするF_SETPIPE_SZを備えたfcntlがあります。
O_NONBLOCKを使用すると、部分的な書き込みと遅延書き込みを実行できます。ただし、O_NONBLOCKが有効になっているが、パイプに書き込まれるバイト数がPIPE_BUFより大きい場合、パイプがいっぱいの場合は書き込みが失敗します。それ以外の場合は、writeの戻り値に基づいて、他のプロセスからのデータとインターリーブされます。 。
オプション-B
を使用してみてください。64kのバッファーのみを使用します。
cat /dev/sda1 | less -B
man less
から:
-Bまたは--auto-buffersデフォルトでは、データがパイプから読み取られると、バッファーは必要に応じて自動的に割り当てられます。パイプから大量のデータが読み取られると、大量のメモリが割り当てられる可能性があります。 -Bオプションは、パイプへのバッファーのこの自動割り当てを無効にするため、パイプには64K(または-bオプションで指定されたスペースの量)のみが使用されます。警告:-Bを使用すると、ファイルの最後に表示された部分のみがメモリに保持されるため、誤った表示が発生する可能性があります。以前のデータはすべて失われます。