web-dev-qa-db-ja.com

パイプラインで無制限の量のデータをバッファリングするユーティリティ?

パイプラインに固執して読み取り速度と書き込み速度を分離できるユーティリティはありますか?

$ producer | buf | consumer

基本的に、入力をできるだけ速く読み取り、メモリに保存するユーティリティbufが必要です。これにより、consumerができるだけ速く実行されている間、producerが時間を費やすことができます。

14
Doctor J

pv (パイプビューア)ユーティリティはこれを行うことができます(-Bオプション)および進捗レポートの提供など、さらに多くの機能があります。

14
David Schwartz

ddを使用できます:

producer | dd obs=64K | consumer

すべてのUNIXで利用できます。

9
Michał Šrajer

mbuffer を見てください。メモリまたはメモリマップトファイルにバッファリングできます(-t/-T)。

これは基本的に否定的な答えです。 ddmbufferも、pvも機能しないようです。特に、プロデューサーによって生成されるデータのレートが大きく変動する可能性がある場合はそうです。以下にいくつかのテストケースを示します。コマンドを入力した後、約10秒間待ってから、>と入力します(データの最後に移動します。つまり、入力の終わりを待ちます)。

zsh -c 'echo foo0; sleep 3; \
        printf "Line %060d\n" {1..123456}; \
        echo foo1; sleep 5; \
        echo foo2' | dd bs=64K | less

ここで、>と入力した後、5秒間待つ必要があります。これは、プロデューサー(zshスクリプト)がsleep 5の前にブロックしたことを意味します。 bsサイズを次のように増やします。 32MBのバッファは十分に大きいですが、32Mは動作を変更しません。これは、ddが入力を続行するのではなく、出力をブロックするためだと思います。 oflag=nonblockを使用すると、データが破棄されるため、解決策にはなりません。

zsh -c 'echo foo0; sleep 3; \
        printf "Line %060d\n" {1..123456}; \
        echo foo1; sleep 5; \
        echo foo2' | mbuffer -q | less

mbufferの場合、問題は最初の行(foo0)がすぐに表示されないことです。入力でラインバッファリングを有効にするオプションはないようです。

zsh -c 'echo foo0; sleep 3; \
        printf "Line %060d\n" {1..123456}; \
        echo foo1; sleep 5; \
        echo foo2' | pv -q -B 32m | less

pvを使用すると、動作はddと同様になります。さらに悪いことに、lessが端末からの入力を受信できなくなることがあるため、端末に対して間違った処理を行うのではないかと思います。たとえば、qで終了することはできません。

1
vinc17

非標準の移動:ソケットバッファを使用します。

例:

# echo 2000000000 > /proc/sys/net/core/wmem_max
$ socat -u system:'pv -c -N i /dev/zero',sndbuf=1000000000 - | pv -L 100k -c -N o > /dev/null
        i:  468MB 0:00:16 [ 129kB/s] [  <=>                        ]
        o: 1.56MB 0:00:16 [ 101kB/s] [       <=>                   ]

このために2つの追加ツールを実装しました: buffered_pipeline および mapopentounixsocket

$ ./buffered_pipeline ! pv -i 10 -c -N 1 /dev/zero ! $((20*1000*1000)) ! pv -i 10 -L 100k -c -N 2 ! > /dev/zero
        1: 13.4MB 0:00:40 [ 103kB/s] [         <=>      ]
        2: 3.91MB 0:00:40 [ 100kB/s] [         <=>      ]
0
Vi.