Bash(または他のシェル)スクリプトで定義されたパイプのパイプ容量を設定する方法はありますか?例えば
cmd1 | cmd2
最近のLinuxでは、パイプサイズはデフォルトで64KBに設定されています。 2つのプロセス間に「バッファリングされる」データの量を制御する2つの方法があることを知っています。
- 用途
buffer(1)
:例:cmd1 | buffer | cmd2
fcntl(2)
F_SETPIPE_SZ
内部cmd1
または外部の標識で使用cmd2
各ソリューションには欠点があります。buffer
バッファを増やすためにのみ使用でき、デフォルトのパイプ容量への書き込みにはまだダウンストリームコマンドを起動する必要があります。私が知っている限り、またはfcntl
内部でのみ呼び出すことができます。cmd1
cmd2
私の質問は:シェルがパイプを作成するときにパイプにどの容量が必要かをシェルで指定する方法はありますか?
答え1
デフォルトのパイプ容量に書き込むには、まだダウンストリームコマンドを起動する必要があります。
ダウンストリームコマンドをあまり頻繁に覚醒させないことが目標である場合は、この-p
オプションを試してみましたかbuffer
?buffer
バッファが特定の割合で満たされるまで書き込みは保持されます。-s
大きな塊として書き込むには、このオプションが必要な場合があります。
更新:ああ、コマンド間の配管はまだいくつかの点を制限します。おそらく次のアダプタプログラムを試してください。
#define _GNU_SOURCE
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
int main(int argc, char** argv)
{
fcntl(atoi(argv[1]), F_SETPIPE_SZ, atoi(argv[2]));
execvp(argv[3],argv+3);
while (1);
}
良い:
adapter 1 (BIGSIZE) cmd1 | cmd2
でも:
adapter 1 (BIGSIZE) cmd1 | adapter 1 (BIGSIZE) buffer [args] | cmd2
cmd1
それでも小さな書き込みが行われている場合。
答え2
DepressedDanielとStéphane Chazelasのアドバイスに従って、私は一行の内容に最も近いものを選びました。
function hugepipe {
perl -MFcntl -e 'fcntl(STDOUT, 1031, 1048576) or die $!; exec { $ARGV[0] } @ARGV or die $!' "$@"
}
これにより、次の作業が可能になります。
hugepipe <command> | <command>
2 つのコマンド間のパイプは、fcntl
perl スクリプトで指定した容量を持ちます。