我有一個目錄,其中包含幾個帶有名稱的子目錄
1
2
3
4
backup_1
backup_2
我撰寫了一個并行化的 bash 代碼來處理這些檔案夾中的檔案,一個最小的作業示例如下:
#!/bin/bash
P=`pwd`
task(){
dirname=$(basename $dir)
echo $dirname running >> output.out
if [[ $dirname != "backup"* ]]; then
sed -i "s/$dirname running/$dirname is good/" $P/output.out
else
sed -i "s/$dirname running/$dirname ignored/" $P/output.out
fi
}
for dir in */; do
((i=i%8)); ((i ==0)) && wait
task "$dir" &
done
wait
echo all done
腳本末尾的“等待”應該等待所有行程完成,然后再繼續回顯“全部完成”。所有行程完成后的 output.out 檔案應顯示
1 is good
2 is good
3 is good
4 is good
backup_1 ignored
backup_2 ignored
如果我將腳本設定為與((i=i%1)); ((i ==0)) && wait
. 但是,如果我與 并行運行它((i=i%2)); ((i ==0)) && wait
,我會得到類似
2 is good
1 running
3 running
4 is good
backup_1 running
backup_2 ignored
誰能告訴我為什么在這種情況下等待不起作用?
我也知道 GNU parallel 可以在并行化任務中做同樣的事情。但是,我不知道如何并行命令在父目錄中的所有子目錄上運行此任務。如果有人可以制作我可以遵循的示例腳本,那就太好了。
非常感謝 Jacek
uj5u.com熱心網友回復:
移植到 GNU Parallel 的文字如下所示:
task(){
dir="$1"
P=`pwd`
dirname=$(basename $dir)
echo $dirname running >> output.out
if [[ $dirname != "backup"* ]]; then
sed -i "s/$dirname running/$dirname is good/" $P/output.out
else
sed -i "s/$dirname running/$dirname ignored/" $P/output.out
fi
}
export -f task
parallel -j8 task ::: */
echo all done
正如其他人指出的那樣,當您sed
并行運行同一個檔案時,您會遇到競爭條件。
為避免競爭條件,您可以執行以下操作:
task(){
dir="$1"
P=`pwd`
dirname=$(basename $dir)
echo $dirname running
if [[ $dirname != "backup"* ]]; then
echo "$dirname is good" >&2
else
echo "$dirname ignored" >&2
fi
}
export -f task
parallel -j8 task ::: */ >running.out 2>done.out
echo all done
你最終會得到兩個檔案 running.out 和 done.out。
如果您真的只想忽略名為 的目錄backup*
:
task(){
dir="$1"
P=`pwd`
dirname=$(basename $dir)
echo $dirname running
echo "$dirname is good" >&2
}
export -f task
parallel -j8 task '{=/backup/ and skip()=}' ::: */ >running.out 2>done.out
echo all done
考慮花 20 分鐘閱讀https://doi.org/10.5281/zenodo.1146014 的第 1 2 章,您的命令列會因此而喜歡您。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/361169.html
標籤:猛击 并行处理 等待 gnu-parallel