Bash(または他のシェル)スクリプトで定義されたパイプのパイプ容量を設定する方法はありますか?たとえば、.
_cmd1 | cmd2
_
最近のLinuxでは、パイプ容量はデフォルトで64KBに設定されています。 2つのプロセス間で「バッファリング」されるデータの量を2つの方法で制御できることを私は知っています。
buffer(1)
の使用:例: _cmd1 | buffer | cmd2
_F_SETPIPE_SZ
_または_cmd1
_の内部から_cmd2
_フラグを指定してfcntl(2)
を使用する各ソリューションには欠点があります。buffer
はバッファーを増やすためにのみ使用できます。また、デフォルトのパイプ容量を上書きするには、ダウンストリームコマンドをウェイクアップする必要があります。 fcntl
は、私が知る限り、_cmd1
_または_cmd2
_の内部からのみ呼び出すことができます。
私の質問は、シェルがパイプを作成するときに、パイプに必要な容量をシェルで指定する方法はありますか?
DepressedDanielとStéphaneChazelasの提案に基づいて、私が見つけたワンライナーに最も近いものに落ち着きました。
function hugepipe {
Perl -MFcntl -e 'fcntl(STDOUT, 1031, 1048576) or die $!; exec { $ARGV[0] } @ARGV or die $!' "$@"
}
これにより、次のことが可能になります。
hugepipe <command> | <command>
2つのコマンド間のパイプは、Perlスクリプトのfcntl
を介して指定された容量になります。
デフォルトのパイプ容量を超えて書き込む場合でも、ダウンストリームコマンドをウェイクアップする必要があります
ダウンストリームコマンドを頻繁にウェイクアップしないことが目標である場合、-p
オプションをbuffer
に使用してみましたか?バッファが特定のパーセンテージまでいっぱいになるまで、buffer
が書き込みを保持するようにする必要があります。大きなチャンクを書き込むには、-s
オプションも必要になる場合があります。
更新:D'oh、コマンド間のパイプはまだ物事を制限します。たぶん、次のアダプタプログラムを使用してみてください。
#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
がまだ小さな書き込みを行う場合。