web-dev-qa-db-ja.com

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

私は以下を持っています、私はそれがサブシェルを並行して実行したと思いました、しかしそれは実際にはそれらを直列に実行しているようです、そして私は理由を理解できません:

#!/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"  &

) &

現在は並行して実行されていますが、スクリプト全体が終了することはなく、実際には終了コードを正確にキャプチャしていないのではないかと心配しています。

2
Alexander Mills

記述されているスクリプトには、いくつかの「問題」があります。私がしたことは、スクリプトをコピーすることでした。テストと評価の目的で、mongorestoresleep 9999に置き換えたり、echoトレースメッセージを挿入したりして、スクリプトを単純化しました。ログファイルに追加します。それの長短は、あなたが必要であると私には思われないということですanyトラップ; 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コマンドは何らかのエラーで失敗するはずです。つまり、スクリプトは常に終了します。エラー。

1
user1404316