私のスクリプトでは、データセットを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
は同じプロセスグループに配置されます。mksh
set -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
リダイレクトはログを保存するためのものです。あなたはおそらくそれをしたくないでしょう。