更新:雖然沒有真正解決帶有問候我管的努力原來的問題,我已經解決了我的問題通過大大簡化它,並且完全拋棄管道。這是一個概念證明腳本,它可以並行生成一次,同時從磁盤讀取一次CRC32,MD5,SHA1,SHA224,SHA256,SHA384和SHA512校驗和,並將它們作爲JSON對象返回(將使用PHP中的輸出和Ruby)。這是沒有錯誤檢查粗糙,但它的工作原理:可能的競爭條件
#!/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。最初,我只是一個簡單的腳本,寫了一個簡單的腳本,用三個cfv命令寫了三個cfv命令,然後寫入/ tmp /下的三個單獨的文件,然後嘗試將它們提供給標準輸出,但最終除非我在嘗試讀取文件之前讓腳本睡了一秒,否則會產生空輸出。這種想法很奇怪,我認爲我在我的腳本中是一個白癡,所以我試圖通過讓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
但是,隨着註釋掉睡眠1秒我一開始預期的輸出,
[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接收者,它派生的數據已經退出,因此回聲「EOP」聲明將前直到所有的cfv子流完成,這意味着他們已經將他們的輸出寫到我命名的管道中了......然後echo語句會執行。
由於行爲是沒有管相同,只是用輸出的臨時文件,我想這一定是具有三通將數據推到它的接受者的方式做一些競爭條件?我嘗試了一個簡單的「等待」命令,但它當然會等待我的bash子進程 - 即while循環 - 完成,所以我只是得到一個掛起的進程。
任何想法?
TIA, 丹尼爾:)一旦寫輸入的最後一位到最後輸出管道,並將其關閉(
我期望有這些校驗和的源代碼可用。如何將它們組合成1個程序,並將3個值寫入相應的校驗和文件。我不得不相信,perl可能有這個模塊,你可以一起做一個文件傳遞。 (只是想着這個盒子,YRMV)。祝你好運! – shellter 2012-03-10 01:25:51
這會有幫助嗎? 'parallel --group'cfv -C -t sfv -f {} - ; cfv -C -t sha1 -f {} - ; cfv -C -t md5 -f {} - ;' ::: file' – potong 2012-03-10 01:46:36
@shelter - 我想寫我自己的例程總是我的後備,但我更願意使用盡可能多的工具。 – DanielSmedegaardBuus 2012-03-10 08:32:26