生成された子プロセスが失敗した場合は、すべての子プロセスを終了して終了します。

生成された子プロセスが失敗した場合は、すべての子プロセスを終了して終了します。

私のスクリプトでは、データセットをinput_aa、input_abなどに分割しました。その後、次のように同じPythonスクリプトで各データセットを実行しました。

# Execute program on each split file
for part in input_*; do
        python3 $part &
done
wait

私の質問は2つあります。 Pythonプロセスの失敗をどのように検出しますか?検出されたら、生成されたすべてのサブプロセスを終了し、失敗でスクリプトを終了するにはどうすればよいですか?

答え1

プロセスグループを使用できます。

set -m
(
   for part in input_*; do
     (python3 "$part" || kill 0) &
   done
   wait
)

set -m(およびオプションの POSIX シェル機能、必須 Unix シェル機能) 独自のプロセスグループでジョブを実行します。bash、、、yashではサブシェルがアクティブな操作であるため、外部プロセスとその中に作成されたすべてのプロセスzshは同じプロセスグループに配置されます。mkshset -m(...)

dash他のシェルベースのケースと同様に、ashこれはトップレベルのシェルプロセスにのみ適用されます。したがって、コードをサブシェルに入れないと、コードは機能します。

kshこれはAT&Tや以前のSysV/Bourneシェルではまったく機能しません。

kill 0現在のプロセスグループのすべてのメンバーにSIGTERMシグナルを送信します。

答え2

ここに例があります。必要なものを入手するには、まず試してください。このまま台無しにすることはできません。

#!/bin/bash
# Example of killing off all children

> killfile
> outfile.err
kill_em()
{
   echo 'killing all children ' > 2
   while read pid
   do
      kill -0 $pid && kill -9 $pid  # if still running kill it
   done < killfile
   exit 1
}

export grandparentpid=$$
trap 'kill_em' 6
for i in 2 2 3 4 5 6 7 8 9 10
do
        ( sleep $i && ls oinkle  >> outfile 2>> outfile.err &
          pid=$!
          echo $pid >> killfile
          wait $!
          [ $? -ne 0 ] && kill -6 $grandparentpid
        ) &
done
wait

ls oinkleこれは(マイコンピュータで)失敗するため、意図的な設定です。

起動スクリプトを修正した後に必要なものを取得したら、---次を変更します。

for i in 2 2 3 4 5 6 7 8 9 10

到着する:

for part in input_* 

変更:

sleep $i && ls oinkle 

到着する:

python3 $part 

リダイレクトはログを保存するためのものです。あなたはおそらくそれをしたくないでしょう。

関連情報