我正在尝试使用python同时在多个单独的终端实例中启动命令。做这个的最好方式是什么?现在我正在尝试使用带有popen的子进程模块,该模块适用于一个命令但不适用于多个命令。
提前致谢。
编辑:
这是我正在做的事情:
from subprocess import*
Popen('ant -Dport='+str(5555)+ ' -Dhost='+GetIP()+ ' -DhubURL=http://192.168.1.113:4444 -Denvironment=*firefox launch-remote-control $HOME/selenium-grid-1.0.8', shell=True)
对我来说问题是这会在终端中启动一个java进程,我希望它继续运行indefinatley。其次,我想在多个不同的进程中多次运行类似的命令。
答案 0 :(得分:1)
只要进程正在运行,它就应该保持打开状态。如果您想同时启动多个,只需将其包装在thread
中未经测试的代码,但你应该得到一般的想法:
class PopenThread(threading.Thread):
def __init__(self, port):
threading.Thread.__init__(self)
self.port=port
def run(self):
Popen('ant -Dport='+str(self.port)+ ' -Dhost='+GetIP()+
' -DhubURL=http://192.168.1.113:4444'
' -Denvironment=*firefox launch-remote-control'
' $HOME/selenium-grid-1.0.8', shell=True)
if '__main__'==__name__:
PopenThread(5555).start()
PopenThread(5556).start()
PopenThread(5557).start()
编辑:这里描述的双叉方法:迈克的https://stackoverflow.com/a/3765162/450517将是启动守护进程的正确方法,即一个长时间运行的进程,它不会每个stdio进行通信。
答案 1 :(得分:1)
我能想出的简单答案是让Python使用Popen
来启动类似于的脚本脚本:
gnome-terminal --window -e 'ant -Dport=5555 -Dhost=$IP1 -DhubURL=http://192.168.1.113:4444 -Denvironment=*firefox launch-remote-control $HOME/selenium-grid-1.0.8' &
disown
gnome-terminal --window -e 'ant -Dport=5555 -Dhost=$IP2 -DhubURL=http://192.168.1.113:4444 -Denvironment=*firefox launch-remote-control $HOME/selenium-grid-1.0.8' &
disown
# etc. ...
有一种完全Python的方法可以做到这一点,但它很难看,只适用于类Unix操作系统,我没有时间编写代码。基本上,subprocess.Popen
不支持它,因为它假定您要等待子进程完成,与子进程交互或监视子进程。它不支持“只是启动它,不要再打扰它了”的情况。
在类Unix操作系统中完成的方法是:
fork
生成子流程fork
成为自己的子进程/dev/null
,然后使用其中一个exec
函数启动您真正想要启动的进程(可能可以使用Popen
这部分)SIGCHLD
信号,如果祖父母终止了,就不会杀死所有的孙子。我可能会关注细节,但这就是要点。 &
中的背景(disown
)和bash
应该可以完成同样的事情。
答案 2 :(得分:0)
这是一个阻塞队列的糟糕版本。你可以使用collections.deque之类的方法来对它进行幻想,或者甚至可以使用Twisted deferreds,或者什么不是。可怜的部分包括:
import logging
basicConfig = dict(level=logging.INFO, format='%(process)s %(asctime)s %(lineno)s %(levelname)s %(name)s %(message)s')
logging.basicConfig(**basicConfig)
logger = logging.getLogger({"__main__":None}.get(__name__, __name__))
import subprocess
def wait_all(list_of_Popens,sleep_time):
""" blocking wait for all jobs to return.
Args:
list_of_Popens. list of possibly opened jobs
Returns:
list_of_Popens. list of possibly opened jobs
Side Effect:
block until all jobs complete.
"""
jobs = list_of_Popens
while None in [j.returncode for j in jobs]:
for j in jobs: j.poll()
logger.info("not all jobs complete, sleeping for %i", last_sleep)
time.sleep(sleep_time)
return jobs
jobs = [subprocess.Popen('sleep 1'.split()) for x in range(10)]
jobs = wait_all(jobs)