Bash脚本杀死Ctrl + C上的后台(大)子级

问题描述 投票:5回答:2

我有一个Bash脚本(Bash 3.2,Mac OS X 10.8),该脚本并行调用多个Python脚本,以便更好地利用多个内核。每个Python脚本都需要很长时间才能完成。

问题是,如果我在Bash脚本的中间按Ctrl + C,实际上不会杀死Python脚本。我如何编写Bash脚本,以便杀死它也将杀死它的所有背景子级?

这是我最初的“精简测试用例”。不幸的是,我似乎已将其减少了很多,以致不再显示问题。我的错。

set -e

cat >work.py <<EOF
import sys, time
for i in range(10):
    time.sleep(1)
    print "Tick from", sys.argv[1]
EOF

function process {
    python ./work.py $1 &
}

process one
process two
wait

这里是一个完整的测试用例,但仍大大减少了,但是希望这可以证明问题所在。它在我的机器上复制...但是两天前,我认为old测试用例在我的机器上复制,而今天肯定没有。

#!/bin/bash -e
set -x

cat >work.sh <<EOF
for i in 0 1 2 3 4 5 6 7 8 9; do
    sleep 1; echo "still going"
done
EOF
chmod +x work.sh

function kill_all_jobs { jobs -p | xargs kill; }
trap kill_all_jobs SIGINT

function process {
    ./work.sh $1
}

process one &
wait $!
echo "All done!"

即使在Ctrl + C之后,此代码仍继续打印still going。但是,如果我将&process的外部移到内部(即:./work.sh $1 &),则Ctrl + C会按预期工作。我一点都不明白!

在我的真实脚本中,process包含多个命令,这些命令长时间运行,必须按顺序运行;因此,在这种情况下,我不知道如何“将&移入process”。我敢肯定这是有可能的,但它一定是不平凡的。

$ bash --version
GNU bash, version 3.2.48(1)-release (x86_64-apple-darwin12)
Copyright (C) 2007 Free Software Foundation, Inc.

编辑:非常感谢@AlanCurry教给我一些Bash知识。不幸的是,我仍然不完全理解示例中发生的事情,但这实际上是有争议的,因为Alan also指出,对于我的实际并行化问题,Bash是错误的工具,我应该使用带有make -j3的简单makefile! make在可能的情况下并行运行事物,并且也能很好地理解Ctrl + C;问题已解决(即使问题尚未解决)。

bash shell process wait kill
2个回答
1
投票
cat >work.py <<'EOF' import sys, time, signal signal.signal(signal.SIGINT, signal.SIG_DFL) for i in range(10): time.sleep(1) print "Tick from", sys.argv[1] EOF chmod +x work.py function process { python ./work.py $1 } process one & wait $! echo "All done!"

1
投票
$ bash --version GNU bash, version 3.2.48(1)-release (x86_64-apple-darwin11) Copyright (C) 2007 Free Software Foundation, Inc. $ cat ./thang #! /bin/bash set -e cat >work.py <<EOF import sys, time for i in range(10): time.sleep(1) print "Tick from", sys.argv[1] EOF function process { python ./work.py $1 & } function killstuff { jobs -p | xargs kill } trap killstuff SIGINT process one process two wait $ ./thang Tick from one Tick from two Tick from one Tick from two ^C$ ps aux | grep python | grep -v grep $
© www.soinside.com 2019 - 2024. All rights reserved.