2016-10-24 1 views
2

バックグラウンドでいくつかのことを実行してスピードを上げたいCIスクリプトがあります。私は、スクリプトがすべてのプロセスを待って、それぞれのプロセスが失敗したかどうかを確認します。ここでバックグラウンドでいくつかのコマンドを実行することはできますが、すべての結果を待ってコマンドが失敗した場合はスクリプトに失敗します。

簡素化:

#!/bin/bash 

set -e 

bg() 
{ 
    sleep .$[ ($RANDOM % 10) + 1 ]s 
} 

bg2() 
{ 
    sleep .$[ ($RANDOM % 10) + 1 ]s 
    exit 1 
} 

bg & # will pass after a random delay 
bg2 & # will fail after a random delay 


# I want the output of the program to be a failure since bg2 fails 

答えて

2

はい。

bashwaitコマンドを使用すると、1つ以上のサブプロセスの完了を待って終了することができます。その場合は、PIDを待機させます。また、waitはオプションで引数を取ることができず、その場合にはすべてのバックグラウンドプロセスが終了するのを待ちます。

例: -

#!/bin/bash 

sleep 3 & 

wait "$!"  # Feeding the non-zero process-id as argument to wait command. 
       # Can also be stored in a variable as pid=$(echo $!) 

# Waits until the process 'sleep 3' is completed. Here the wait 
# on a single process is done by capturing its process id 

echo "I am waking up" 

sleep 4 & 
sleep 5 & 

wait   # Without specifying the id, just 'wait' waits until all jobs 
       # started on the background is complete. 

# (or) simply 
# wait < <(jobs -p)  # To wait on all background jobs started with (job &) 

echo "I woke up again" 

アップデート: -

が失敗したジョブを識別するためには、それがバックグラウンドジョブのリストをループして、視認性のために彼らの出口コードをログに記録するのが最善です。 chepnerによる素晴らしい提案に感謝します。 `何

#!/bin/bash 
for p in $(jobs -p) 
do 
    wait "$p" || { echo "job $p failed" >&2; exit; } 
done 
+0

のようにそれを行く "$を!" '最初の待機コマンドでやる? – Robert

+0

@Robert:バックグラウンドジョブのprocess-idを取得するために、waitコマンドの引数として渡される非ゼロの整数。 – Inian

+2

これは、元の質問からの重要な側面、すなわち、バックグラウンドジョブが失敗した場合の失敗が欠落しています。複数のバックグラウンドプロセスを待っていると、終了ステータスに関する情報が失われます。ジョブが成功するか失敗するかを個別に確認する必要があります。 – chepner

1
#!/bin/bash 

set -e 

bg() 
{ 
    sleep .$[ ($RANDOM % 10) + 1 ]s 
} 

bg2() 
{ 
    sleep .$[ ($RANDOM % 10) + 1 ]s 
    exit 1 
} 

export -f bg 
export -f bg2 

parallel ::: bg bg2 || echo $? of the jobs failed 
+0

クール、私はhttps://www.gnu.org/software/をインストールする必要がありますパラレル/? – Robert

+0

あなたは正しく推測します。しかし、あなたがそれを行うためにrootアクセスを必要としないことに注意してください。 –

関連する問題