我们有一个用Python编写的大型应用程序。我们希望在关闭或中断应用程序时干净地杀死应用程序启动的进程。但是,通过Python代码(例如subprocess.Popen或os.system),我们有一个命令 A ,它启动另一个子命令 B ,但命令 B 似乎与命令 A 无关。命令 B 的父进程是init进程(使用pid 1)。如何在Python代码中终止进程 B (例如在Ctrl + C之后)?
例如,我们有2个shell脚本和一个调用这些shell脚本的Python脚本。
第一个Shell脚本 mycommand1.sh 是:
#!/bin/sh
sleep 3600 &
第二个Shell脚本 mycommand2.sh 是:
#!/bin/sh
sleep 3600
Python脚本 myscript.py 是:
import os
import signal
import subprocess
def launchCommands():
proc1 = subprocess.Popen('./mycommand1.sh', stdout=subprocess.PIPE, shell = True, preexec_fn=os.setsid)
print "the processus 1 has started"
proc2 = subprocess.Popen('./mycommand2.sh', stdout=subprocess.PIPE, shell = True, preexec_fn=os.setsid)
print "the processus 2 has started"
return proc1, proc2
if __name__ == '__main__':
proc1 = None
proc2 = None
try:
proc1, proc2 = launchCommands()
while True:
pass
except KeyboardInterrupt:
print "Ctrl+C received! ..."
print "trying to kill the processus 2"
os.killpg(os.getpgid(proc2.pid), signal.SIGTERM)
print "processus 2 has been killed"
print "trying to kill the processus 1"
os.killpg(os.getpgid(proc1.pid), signal.SIGTERM)
print "processus 1 has been killed"
然后我们执行Python脚本,然后用Ctrl + C在3秒后中断它。 这是中断后的输出。
$> python myscript.py
the processus 1 has started
the processus 2 has started
^CCtrl+C received! ...
trying to kill the processus 2
processus 2 has been killed
trying to kill the processus 1
Traceback (most recent call last):
File "myscript.py", line 33, in <module>
os.killpg(os.getpgid(proc1.pid), signal.SIGTERM)
OSError: [Errno 3] No such process
我们在执行Python脚本的同时和之后显示所有“睡眠”进程(当然,在执行Python脚本之前没有睡眠过程)。
运行myscript.py命令时:
$> ps -ef | grep sleep
501 50700 1 0 2:21 ?? 0:00.00 sleep 3600
501 50701 50699 0 2:21 ?? 0:00.00 sleep 3600
501 50703 410 0 2:21 ttys002 0:00.00 grep sleep
用Ctrl + C中断程序后:
$> ps -ef | grep sleep
501 50700 1 0 2:21 ?? 0:00.00 sleep 3600
501 51025 410 0 2:23 ttys002 0:00.00 grep sleep
正如我们所看到的,我们尝试杀死的进程1不再存在,并且父进程为1的进程休眠始终存在。此进程睡眠来自脚本mycommand1.sh的执行。如何正确杀死这个进程睡眠脚本myscript.py(当然,我们不希望杀死所有的睡眠过程)?
答案 0 :(得分:0)
尝试重写mycommand1.sh
#!/bin/sh
foo(){
cnt=0
while [ $cnt -le 100 ]; do
cnt=$((cnt+1))
echo $0 $cnt
sleep 1
done
}
foo &
和mycommand2.sh
#!/bin/sh
foo(){
cnt=0
while [ $cnt -le 100 ]; do
cnt=$((cnt+1))
echo $0 $cnt
sleep 1
done
}
foo
从stdout=subprocess.PIPE
移除myscript.py
检查一下。