afr*_*las 19 python unix subprocess
我正在使用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)
Run Code Online (Sandbox Code Playgroud)
一旦自动化测试完成,该过程应该被杀死.我正在使用os.kill这个:
os.killpg(selenium_server_process.pid, signal.SIGTERM)
selenium_server_process.wait()
Run Code Online (Sandbox Code Playgroud)
这不起作用.原因是shell子进程为java生成了另一个进程,并且我的python代码不知道该进程的pid.我已经尝试过杀死进程组os.killpg,但是这也会杀死运行此代码的python进程.由于其他原因,将shell设置为false,从而避免java在shell环境中运行也是不可能的.
如何杀死shell以及由它生成的任何其他进程?
ber*_*rio 29
处理一般问题:
p=subprocess.Popen(your_command, preexec_fn=os.setsid)
os.killpg(os.getpgid(p.pid), signal.SIGTERM)
Run Code Online (Sandbox Code Playgroud)
setsid将在新会话中运行该程序,从而为其及其子项分配新的进程组.os.killpg因此调用它也不会降低你自己的python进程.
在这种情况下,显而易见的解决方案是不涉及 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)
Run Code Online (Sandbox Code Playgroud)
这将使该进程直接成为Java进程。请记住,它可能仍然会生成不属于进程组的进程,因此 os.killpg 可能仍然不知道如何杀死它们。
如果您有理由调用 shell(上面的代码没有,并且没有 shell,您无法做一些事情,但假设您这样做),则必须让 shell 向您传递它启动的进程的 pid不知何故。这样做并不简单,而且要视情况而定。