python - subprocess.Popen().pid 返回父脚本的pid

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31039972/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 09:22:26  来源:igfitidea点击:

python - subprocess.Popen().pid return the pid of the parent script

pythonsubprocess

提问by farhawa

I am trying to run a Python script from another Python script, and getting its pidso I can kill it later.

我正在尝试从另一个 Python 脚本运行一个 Python 脚本,并获取它pid以便我以后可以杀死它。

I tried subprocess.Popen()with argument shell=True', but thepidattribute returns thepid` of the parent script, so when I try to kill the subprocess, it kills the parent.

我尝试subprocess.Popen()使用父脚本的参数shell=True', but thepid attribute returns thepid`,因此当我尝试终止子进程时,它会终止父进程。

Here is my code:

这是我的代码:

proc = subprocess.Popen(" python ./script.py", shell=True)
pid_ = proc.pid
.
.
.
# later in my code

os.system('kill -9 %s'%pid_)

#IT KILLS THE PARENT :(

回答by icktoofay

So run it directly without a shell:

所以不用shell直接运行:

proc = subprocess.Popen(['python', './script.py'])

By the way, you may want to consider changing the hardcoded 'python'to sys.executable. Also, you can use proc.kill()to kill the process rather than extracting the PID and using that; furthermore, even if you did need to kill by PID, you could use os.killto kill the process rather than spawning another command.

顺便说一句,您可能需要考虑将硬编码更改'python'sys.executable. 此外,您可以使用proc.kill()来终止进程,而不是提取 PID 并使用它;此外,即使您确实需要通过 PID 终止,您也可以使用os.kill终止进程而不是生成另一个命令。

回答by jfs

shell=Truestarts a new shell process. proc.pidis the pid of that shell process. kill -9kills the shell process making the grandchild python process into an orphan.

shell=True启动一个新的 shell 进程。proc.pid是那个shell进程的pid。kill -9杀死 shell 进程,使孙子 python 进程成为孤儿。

If the grandchild python script can spawn its own child processes and you want to kill the whole process tree then see How to terminate a python subprocess launched with shell=True:

如果孙子 python 脚本可以产生自己的子进程,并且您想终止整个进程树,那么请参阅如何终止使用 shell=True 启动的 python 子进程:

#!/usr/bin/env python
import os
import signal
import subprocess

proc = subprocess.Popen("python script.py", shell=True, preexec_fn=os.setsid) 
# ...
os.killpg(proc.pid, signal.SIGTERM)

If script.pydoes not spawn any processes then use @icktoofay suggestion: drop shell=True, use a list argument, and call proc.terminate()or proc.kill()-- the latter always works eventually:

如果script.py没有产生任何进程,则使用@icktoofay 建议: drop shell=True,使用列表参数,然后调用proc.terminate()or proc.kill()-- 后者最终总是有效:

#!/usr/bin/env python
import subprocess

proc = subprocess.Popen(["python", "script.py"]) 
# ...
proc.terminate()

If you want to run your parent script from a different directory; you might need get_script_dir()function.

如果你想从不同的目录运行你的父脚本;你可能需要get_script_dir()function

Consider importing the python module and running its functions, using its object (perhaps via multiprocessing) instead of running it as a script. Here's code example that demonstrates get_script_dir()and multiprocessingusage.

考虑导入 python 模块并运行其函数,使用其对象(可能通过multiprocessing)而不是将其作为脚本运行。这是演示get_script_dir()multiprocessing用法代码示例