シェルスクリプトを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 ... value
)value=$(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のデータを消費しないことです。書き込み時にdd
65516バイトが読み取られます。これは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