私は以下を持っています。サブシェルを並列に実行すると思いますが、実際にはシリアルで実行しているようで、その理由を理解できません。
#!/usr/bin/env bash
set -e;
set -m # allow for job control
EXIT_CODE=0; # exit code of overall script
function handleJobs() {
for job in `jobs -p`; do
echo "PID => ${job}"
CODE=0;
wait ${job} || CODE=$?
if [[ "${CODE}" != "0" ]]; then
echo "At least one process failed with exit code => ${CODE}" ;
EXIT_CODE=1;
fi
done
}
trap 'handleJobs' CHLD
for file in "$HOME/mongodump_dev/cdt_db/"* ; do
file="$(basename "$file")"
if [[ "$file" != "system"* && "$file" != "locks"* ]]; then
mongorestore \
--db "cdt_dev" \
--collection "${file%.*}" \
--host "<my-host>" \
"$HOME/mongodump_dev/cdt_db/$file" &
fi;
done
wait;
echo "exit code => $EXIT_CODE"
exit "$EXIT_CODE"
サブシェルがシリアルで実行される理由を知っている人はいますか?
私はこれを試みます:
(
mongorestore \
--db "cdt_dev" \
--collection "${file%.*}" \
--host "<my-host>" \
"$HOME/mongodump_dev/cdt_db/$file" &
) &
これで並列に実行されますが、今ではスクリプト全体が終了せず、実際に終了コードを正確にキャプチャできないことが心配です。
答え1
あなたが書いたスクリプトには多くの「問題」があります。私がしたのは、スクリプトをコピーし、テストおよび評価の目的でログファイルに追加されたトレースメッセージを置き換えてmongorestore
挿入sleep 9999
するなどの作業を実行してスクリプトを簡素化することでした。echo
おおむねあなたが必要ではないようですどのわかりました。mongorestore
宣言を次に変更します。
( mongorestore ...
exit_code=$?
[ $exit_code -ne 0 ] \
&& printf "Process %s for file %s failed with exit code %s\n" \
$BASHPID "${file%.*}" $exit_code
) &
しかし、すべての子プロセスが並列に作成されたことを確認する簡単な方法は、他の端末を開きますpgrep -a mongorestore
。
また、スクリプトの最後にEXIT_CODEを使用すると値があってはいけません。したがって、コマンドはエラーの種類によってexit
失敗する必要があります。これは、スクリプトが常にエラーで終了することを意味します。