如果任何产生的子进程失败,请全部杀死并退出


9

在我的脚本中,我将数据集划分为input_aa,input_ab等。然后,我通过相同的Python脚本运行每个数据集,如下所示:

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

我的问题有两个:如何检测到Python进程已失败,如何检测到该错误,如何杀死所有产生的子代并失败退出脚本?

Answers:


10

您可以使用一个流程组:

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

set -m(以及可选的POSIX Shell功能,必需的Unix Shell功能)在其自己的进程组中运行作业。在bashyashzshmksh,这就是子shell的工作set -m被启用,因此外(...),所有内创建的进程将被放置在同一个进程小组。

对于dash和其他ash基于炮弹,那只能在顶级shell进程。因此,除非将其放在子外壳中,否则该代码将起作用。

这在AT&T ksh或旧的SysV / Bourne Shell中根本不起作用。

kill 0 向当前进程组的所有成员发送SIGTERM信号。


猛扑 为什么要包含shebang-所需的外壳不清楚。好的答案
吉姆·麦克纳马拉

@jimmcnamara,在工程bashdashyashmkshzsh。基本上是任何POSIX外壳,但AT&T ksh除外。set -m在POSIX中(不足)指定,但作为可选功能。
斯特凡Chazelas

我使用Solaris。/ bin / sh不会飞。
jim mcnamara 2015年

@jimmcnamara,在Solaris 10和更低版本上没有/ bin / sh,是Bourne shell(不是POSIX shell),在11和AT&T ksh上。如我所说,它可以在bash,dash,yash,mksh,zsh中使用。
斯特凡Chazelas

1
@mikeserv,它将使该流程重设为1,但不会将其从流程组中删除。kill 0杀死进程组的所有成员,无论其父级是什么。请参阅ps -j以查看进程组ID。
斯特凡Chazelas

3

这是一个例子。首先玩这个游戏,以获取您真正需要的东西。它不能破坏很多。

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

重定向在那里保存日志。您可能不想要它们。


这有点讲究。如果其中一个作业在所有其他killfile作业都未启动之前就失败了,则您的作业可能不包含已启动的所有作业的pid。
斯特凡Chazelas

一些不好的做法,如:带引号的变量,利用信号的数字,而不是名称,使用信号6(ABRT在Linux AMD64例如),而不是USR1 / USR2作为用户信号,[ $? -ne 0 ]...
斯特凡Chazelas
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.