パイプから増分を読む

パイプから増分を読む

シェルスクリプトをstdin

#!/bin/bash
value=0
while [ "$value" != "-1" ]; do
  read -r -d '' -n 20 value
  if [ "$value" != "-1" ]; then
    dd conv=notrunc status=none of=/path/bigfile.bin bs=1M count=1 seek=$value
  fi
done

簡単に言えば、大容量ファイルの特定のブロックをリモートの場所にある同じファイルにコピーしようとしています。転送スクリプトから送信されるデータには、ブロック位置(20バイト)とその位置に書き込まれる1MiBのデータがあります。位置が-1になると終了します。

コンパイルされたCプログラムを実行すると、私の設定はうまくいきますが、これを防ぎ、デフォルトのシェルコマンドを使用して実行したいと思います。問題は、ddデータをまったく消費しないようで、すべてのデータがreadコマンドによって処理されることです。

stdin複数のコマンドで使用できますか?

答え1

ですべてを読むことができますdd

これはうまくいきます(read ... valuevalue=$(dd bs=20 count=1 status=none)

#!/bin/bash
value=0
while [ "$value" != "-1" ]; do
  value=$(dd bs=20 count=1 status=none)
  if [ "$value" != "-1" ]; then
    dd conv=notrunc status=none of=/path/bigfile.bin bs=1M count=1 seek=$value
  fi
done

答え2

実際の質問に対する答えは「はい」です。stdinパイプする瞬間から増分読み取りを開始できます。

スクリプトの問題に対する解決策は、ddコマンドが1MiBのデータを消費しないことです。書き込み時にdd65516バイトが読み取られます。これは65536(64KiB)からブロックサイズ20バイトを引いたものです。この限られた量のデータが読み取られた後にdd終了します。解決策はフラグを使用することですiflag=fullblock。また、-1のチェックは作成されたとおりに機能しません。完全な機能ソリューションは次のとおりです。

value=0
while [ $value != -1 ]; do
  read -r -d '' -n 20 value
  value=$((value))
  if [ $value != -1 ]; then
    dd iflag=fullblock conv=notrunc status=none \
      of=/path/bigfile.bin bs=1M count=1 seek=$value
  fi
done

関連情報