サブシェルを並列に実行し、終了コードを収集します。

サブシェルを並列に実行し、終了コードを収集します。

私は以下を持っています。サブシェルを並列に実行すると思いますが、実際にはシリアルで実行しているようで、その理由を理解できません。

#!/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失敗する必要があります。これは、スクリプトが常にエラーで終了することを意味します。

おすすめ記事