我有以下问题:
我需要我的Python脚本运行bash脚本。如果bash脚本运行超过让我们说10秒,我需要杀死它。这就是我到目前为止所做的:
cmd = ["bash", "script.sh", self.get_script_path()]
process = subprocess.Popen(cmd)
time.sleep(10) # process running here...
procinfo = psutil.Process(process.pid)
children = procinfo.children(recursive=True)
for child in children:
os.kill(child.pid, signal.SIGKILL)
我担心的是这种情况:bash脚本在1秒内完成,释放其PID并且系统将PID传递给另一个进程。 10秒后,我杀了PID,我认为它属于我的脚本,但事实并非如此,我杀死了其他一些进程。该脚本需要以root身份运行,因为我需要chroot
。
有什么想法吗?
答案 0 :(得分:2)
由于您已经在使用psutil
,因此我建议您通过调用psutil.Popen
替换对subprocess
模块的调用。此类具有subprocess.Popen
的相同接口,但提供psutil.Process
的所有功能。
另请注意, psutil
库已经先发制人地检查PID重用,至少对于包括terminate
和kill
在内的多种方法(只是阅读documentation for Process
)。
这意味着以下代码:
cmd = ["bash", "script.sh", self.get_script_path()]
process = psutil.Popen(cmd)
time.sleep(10) # process running here...
children = process.children(recursive=True)
for child in children:
child.terminate() # try to close the process "gently" first
child.kill()
请注意children
的文档说:
<强>儿童(递归=假)强>
将此过程的子项作为
Process
个对象的列表返回,先发制人地检查PID是否已被重用。
总之,这意味着:
children
时,psutil
图书馆会检查您是否希望正确流程的子项而不是具有相同pid的子项terminate
或kill
时,图书馆会确保您杀死您的子进程,而不是使用相同pid的随机进程。答案 1 :(得分:0)
我认为timeout
命令对你来说非常合适。从文档页面:
概要
超时 [OPTION] NUMBER [SUFFIX] COMMAND [ARG] ...
超时 [选项]描述
启动COMMAND,如果在NUMBER秒后仍然运行,则将其终止。 SUFFIX可以是's'秒(默认值),'m'表示分钟,'h'表示小时或'd'表示天数。
-s , - 信号 = SIGNAL
指定超时发送的信号 SIGNAL 可以是“HUP”或数字之类的名称 有关信号列表,请参阅'kill -l'
依靠timeout
,您不必担心PID重用,竞争条件等的混乱细节。这些问题很好地封装在这个标准的Unix实用程序中。另一个好处是你的脚本会在子进程提前终止后立即恢复执行,而不是在整整10秒内不必要地休眠。
bash演示:
timeout -s9 10 sleep 11; echo $?;
## Killed
## 137
timeout -s9 10 sleep 3; echo $?;
## 0
python中的演示:
import subprocess;
subprocess.Popen(['timeout','-s9','10','sleep','11']).wait();
## -9
subprocess.Popen(['timeout','-s9','10','sleep','3']).wait();
## 0
答案 2 :(得分:-3)
我在ubuntu上使用命令stop process_name来停止我的进程。 愿它有用。