UPDATE:私の配管工事に関して提示された元の問題を実際に解決していない間に、それを大幅に簡素化し、パイプを完全に排除するだけです。ここでは、ディスクから一度だけ読み取ってCRC32、MD5、SHA1、SHA224、SHA256、SHA384、SHA512のチェックサムを生成し、それらをJSONオブジェクトとして返すコンセプト実証スクリプトを作成します(PHPで出力を使用します)。 Rubyなど)。それをエラーチェックせずに、粗製だが、それは動作します:BASHスクリプト内の名前付きパイプに順序外れして到着した複数のティー受信者からのパイプ出力による競合状態
#!/bin/bash
checksums="`tee <"$1" \
>(cfv -C -q -t sfv -f - - | tail -n 1 | sed -e 's/^.* \([a-fA-F0-9]\{8\}\)$/"crc32":"\1"/') \
>(md5sum - | sed -e 's/^\([a-fA-F0-9]\{32\}\) .*$/"md5":"\1"/') \
>(sha1sum - | sed -e 's/^\([a-fA-F0-9]\{40\}\) .*$/"sha1":"\1"/') \
>(sha224sum - | sed -e 's/^\([a-fA-F0-9]\{56\}\) .*$/"sha224":"\1"/') \
>(sha256sum - | sed -e 's/^\([a-fA-F0-9]\{64\}\) .*$/"sha256":"\1"/') \
>(sha384sum - | sed -e 's/^\([a-fA-F0-9]\{96\}\) .*$/"sha384":"\1"/') \
>(sha512sum - | sed -e 's/^\([a-fA-F0-9]\{128\}\) .*$/"sha512":"\1"/') \
>/dev/null`\
"
json="{"
for checksum in $checksums; do json="$json$checksum,"; done
echo "${json:0: -1}}"
元の質問:
私はその適用後に私の検索フレーズには多くのヒットを得たように私は、この質問をして少し怖いですUsing named pipes with bash - Problem with data lossから収穫された知識と別の20ページを読むと、私はまだこれで少し静止しています。
それでも、ディスク上から一度だけ読み取っている間に、CRC32、MD5、およびSHA1チェックサムを同時にファイルに作成できるようにする簡単なスクリプトを実行しています。私はその目的のためにcfvを使用しています。
元々、/ tmp /の下にある3つの別々のファイルに3つのcfvコマンドを書き込んでファイルをcat'tedしてから、stdoutにキャッチしようとしましたが、ファイルを読み込もうとする前にスクリプトを1秒間スリープさせない限り、空の出力があります。変わったと思ったので、私は自分のスクリプトでは馬鹿だと思ったので、代わりにcfvワーカーを名前付きパイプに出力させることで別のアプローチを試みました。これまでのところ、これはforementionedリンクから技術を適用した後、私のスクリプトです:
ので!/bin/bash
# Bail out if argument isn't a file:
[ ! -f "$1" ] && echo "'$1' is not a file!" && exit 1
# Choose a name for a pipe to stuff with CFV output:
pipe="/tmp/pipe.chksms"
# Don't leave an orphaned pipe on exiting or being terminated:
trap "rm -f $pipe; exit" EXIT TERM
# Create the pipe (except if it already exists (e.g. SIGKILL'ed b4)):
[ -p "$pipe" ] || mkfifo $pipe
# Start a background process that reads from the pipe and echoes what it
# receives to stdout (notice the pipe is attached last, at done):
while true; do
while read line; do
[ "$line" = "EOP" ] && echo "quitting now" && exit 0
echo "$line"
done
done <$pipe 3>$pipe & # This 3> business is to make sure there's always
# at least one producer attached to the pipe (the
# consumer loop itself) until we're done.
# This sort of works without "hacks", but tail errors out when the pipe is
# killed, naturally, and script seems to "hang" until I press enter after,
# which I believe is actually EOF to tail, so it's no solution anyway:
#tail -f $pipe &
tee <"$1" >(cfv -C -t sfv -f - - >$pipe) >(cfv -C -t sha1 -f - - >$pipe) >(cfv -C -t md5 -f - - >$pipe) >/dev/null
#sleep 1s
echo "EOP" >$pipe
exit
、それはスタンドとして実行、私はこの出力を得る:
[email protected]:~/tisso$ ./multisfv file
: : : quitting now
- : Broken pipe (CF)
close failed in file object destructor:
sys.excepthook is missing
lost sys.stderr
- : Broken pipe (CF)
close failed in file object destructor:
sys.excepthook is missing
lost sys.stderr
- : Broken pipe (CF)
[email protected]:~/tisso$ close failed in file object destructor:
sys.excepthook is missing
lost sys.stderr
しかし、睡眠1Sをコメントアウト私は考えていないの出口各CFV受信者の後までそれフォークデータが終了したために、ひいてはエコー「EOP」声明そのTシャツを前提としたいように、私が予想を取得出力、
[email protected]:~/tisso$ ./multisfv file
3bc1b5ff125e03fb35491e7d67014a3e *
-: 1 files, 1 OK. 0.013 seconds, 79311.7K/s
5e3bb0e3ec410a8d8e14fef1a6daababfc48c7ce *
-: 1 files, 1 OK. 0.016 seconds, 62455.0K/s
; Generated by cfv v1.18.3 on 2012-03-09 at 23:45.23
;
2a0feb38
-: 1 files, 1 OK. 0.051 seconds, 20012.9K/s
quitting now
これは、私をパズルだろう元すべてのcfvサブストリームが終了するまで実行してください。そうすれば、私の名前付きパイプに出力を書き込んだのでしょう...そして、echo文が実行されます。
出力テンポラリファイルを使用するだけで、パイプなしで動作が同じであるため、ティーがデータを受信者にプッシュする方法と関係があります。私は単純な "wait"コマンドを試しましたが、もちろんbashの子プロセス(whileループ)が終了するのを待つので、ちょうどぶら下がったプロセスになります。
アイデア?
TIA、 ダニエル:)
これらのチェックサムに使用できるソースコードがあると思います。どのようにそれらを1つのプログラムに結合し、適切なチェックサムファイルに処理する3つの値を書き出すのですか?私はperlがおそらくこのモジュールを持っていると信じなければなりません。もう一度、あなたは一緒にglomをしてファイルを1回だけ渡すことができます。 (ちょうどこれの上にボックスを考える、YRMV)。がんばろう! – shellter
これは役に立ちますか? cfv -C -t sdv -f {} - ; cfv -C -t sha1 -f {} - ; cfv -C -t md5 -f {} - ; 'パラレル - :::ファイル ' – potong
@shelter - 私自身のルーチンを書くことは常に私の後戻りだと思うが、私は可能な限り多くのツールを利用したい。 – DanielSmedegaardBuus