在我的脚本中,我将数据集拆分为 input_aa、input_ab 等。然后,我通过相同的 Python 脚本运行每一个,如下所示:
# Execute program on each split file
for part in input_*; do
python3 $part &
done
wait
Run Code Online (Sandbox Code Playgroud)
我的问题有两个:如何检测 Python 进程失败,以及检测到时,如何杀死所有生成的子进程并以失败退出脚本?
Sté*_*las 10
您可以使用进程组:
set -m
(
for part in input_*; do
(python3 "$part" || kill 0) &
done
wait
)
Run Code Online (Sandbox Code Playgroud)
set -m(以及可选的 POSIX shell 功能,必需的 Unix shell 功能)在它们自己的进程组中运行作业。在bash, yash, zsh, 中mksh,这set -m是启用子外壳的作业,因此外部(...)进程和在其中创建的所有进程将放置在同一个进程组中。
对于dash和其他ash基于 shell 的,仅适用于顶级 shell 进程。因此,除非将其放入子外壳中,否则该代码将起作用。
这在 AT&Tksh或旧的 SysV/Bourne shell 中根本不起作用。
kill 0 向当前进程组的所有成员发送 SIGTERM 信号。
这是一个例子。首先尝试一下以获得您所需要的东西。它不能按原样破坏太多。
#!/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
Run Code Online (Sandbox Code Playgroud)
这是故意失败的,因为ls oinkle会失败(在我的机器上)。
当你在修改启动脚本后得到你需要的东西时---更改:
for i in 2 2 3 4 5 6 7 8 9 10
Run Code Online (Sandbox Code Playgroud)
到:
for part in input_*
Run Code Online (Sandbox Code Playgroud)
改变:
sleep $i && ls oinkle
Run Code Online (Sandbox Code Playgroud)
到:
python3 $part
Run Code Online (Sandbox Code Playgroud)
重定向是为了保存日志。你可能不想要它们。
| 归档时间: |
|
| 查看次数: |
3115 次 |
| 最近记录: |