我正在使用python 2.5上的子进程模块生成一个java程序(准确地说是selenium服务器),如下所示:
import os
import subprocess
display = 0
log_file_path = "/tmp/selenium_log.txt"
selenium_port = 4455
selenium_folder_path = "/wherever/selenium/lies"
env = os.environ
env["DISPLAY"] = ":%d.0" % display
command = ["java",
"-server",
"-jar",
'selenium-server.jar',
"-port %d" % selenium_port]
log = open(log_file_path, 'a')
comm = ' '.join(command)
selenium_server_process = subprocess.Popen(comm,
cwd=selenium_folder_path,
stdout=log,
stderr=log,
env=env,
shell=True)
一旦自动化测试完成,这个过程就会被杀死。我正在使用os.kill
来执行此操作:
os.killpg(selenium_server_process.pid, signal.SIGTERM)
selenium_server_process.wait()
这不起作用。原因是shell子进程为java生成了另一个进程,并且我的python代码不知道该进程的pid。我已经尝试使用os.killpg
来杀死进程组,但这也会杀死首先运行此代码的python进程。由于其他原因,将shell设置为false,从而避免java在shell环境中运行也是不可能的。
如何杀死shell及其生成的任何其他进程?
答案 0 :(得分:27)
处理一般问题:
p=subprocess.Popen(your_command, preexec_fn=os.setsid)
os.killpg(os.getpgid(p.pid), signal.SIGTERM)
setsid
将在新会话中运行程序,从而为其及其子项分配新的进程组。因此调用os.killpg
也不会降低你自己的python进程。
答案 1 :(得分:4)
在这种情况下,显而易见的解决方案是不涉及shell :
import os
import subprocess
display = 0
log_file_path = "/tmp/selenium_log.txt"
selenium_port = 4455
selenium_folder_path = "/wherever/selenium/lies"
env = os.environ
env["DISPLAY"] = ":%d.0" % display
command = ["java",
"-server",
"-jar",
'selenium-server.jar',
"-port",
str(selenium_port)]
log = open(log_file_path, 'a')
selenium_server_process = subprocess.Popen(command,
cwd=selenium_folder_path,
stdout=log,
stderr=subprocess.STDOUT,
env=env)
这将使该过程直接成为Java过程。请记住,它可能仍会产生不属于进程组的进程,因此os.killpg可能仍然不知道如何杀死它们。
如果你有理由调用shell(上面的代码没有,并且没有shell你可以做的事情很少,但假设你这样做),你必须让shell传递给你的pid。过程以某种方式开始。这样做并不简单,而是情境化。