微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

我怎样才能启动一个进程,并把它放到Python的背景?

我目前正在编写我的第一个Python程序(在Python 2.6.6中)。 该程序便于启动和停止运行在提供用户常用命令的服务器上的不同应用程序(例如在Linux服务器上启动和停止系统服务)。

我正在启动应用程序的启动脚本

p = subprocess.Popen(startCommand,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE) output,err = p.communicate() print(output)

问题是,一个应用程序的启动脚本停留在前台,所以p.communicate()永远等待。 我已经尝试在startCommand前面使用“nohup startCommand&”,但没有像预期的那样工作。

作为一种解决方法,我现在使用下面的bash脚本来调用应用程序的启动脚本:

Pythonsubprocess。在Windows上以不同的用户身份打开

如何从Python启动一个命令窗口

用选定的浏览器启动IPython笔记本

如何限制python中的subprocessstdout和stderr的大小

subprocess库不会执行compgen

#!/bin/bash LOGFILE="/opt/scripts/bin/logs/SomeServerApplicationStart.log" nohup /opt/someDir/startSomeServerApplication.sh >${LOGFILE} 2>&1 & STARTUPOK=$(tail -1 ${LOGFILE} | grep "Server started in RUNNING mode" | wc -l) COUNTER=0 while [ $startUPOK -ne 1 ] && [ $COUNTER -lt 100 ]; do STARTUPOK=$(tail -1 logs/SomeServerApplicationStart.log | grep "Server started in RUNNING mode" | wc -l) if (( STARTUPOK )); then echo "STARTUP OK" exit 0 fi sleep 1 COUNTER=$(( $COUNTER + 1 )) done echo "STARTUP Failed"

bash脚本是从我的python代码调用的。 这种解决方法工作完美,但我宁愿做所有的python…

是subprocess.Popen错误的方式? 我怎样才能在Python中完成我的任务?

Django的+ Apache + Windows WsgiDaemonProcess替代

将SIGINT信号委派给subprocess,然后清理并终止父进程

subprocess:在Windows中删除subprocess

Windows服务中的Pythonsubprocess(无pipe道)

使用VLC的虚拟接口时如何防止显示控制台

首先很容易不通过沟通来阻止Python脚本的通信! 只需从命令的输出错误输出读取,直到找到正确的消息,然后忘记命令。

# to avoid waiting for an EOF on a pipe ... def getlines(fd): line = bytearray() c = None while True: c = fd.read(1) if c is None: return line += c if c == 'n': yield str(line) del line[:] p = subprocess.Popen(startCommand,stderr=subprocess.STDOUT) # send stderr to stdout,same as 2>&1 for bash for line in getlines(p.stdout): if "server started in RUNNING mode" in line: print("STARTUP OK") break else: # end of input without getting startup message print("STARTUP Failed") p.poll() # get status from child to avoid a zombie # other error processing

上面的问题是,服务器仍然是Python进程的孩子,可能会得到不必要的信号,如SIGHUP。 如果你想使它成为一个守护进程,你必须先启动一个子进程,然后启动你的服务器。 这样当第一个孩子结束时,可以由调用者等待,服务器将获得1的PPID(由init进程采用)。 您可以使用多处理模块来缓解该部分

代码可能是这样的:

import multiprocessing import subprocess # to avoid waiting for an EOF on a pipe ... def getlines(fd): line = bytearray() c = None while True: c = fd.read(1) if c is None: return line += c if c == 'n': yield str(line) del line[:] def start_child(cmd): p = subprocess.Popen(cmd,stderr=subprocess.STDOUT,shell=True) for line in getlines(p.stdout): print line if "server started in RUNNING mode" in line: print "STARTUP OK" break else: print "STARTUP Failed" def main(): # other stuff in program p = multiprocessing.Process(target = start_child,args = (server_program,)) p.start() p.join() print "DONE" # other stuff in program # protect program startup for multiprocessing module if __name__ == '__main__': main()

有人可能会想,当一个文件对象本身是一次返回一行的迭代器时, getlines生成器的需要是什么。 问题是它内部调用read ,直到文件没有连接到终端EOF。 因为它现在连接到PIPE,所以在服务器结束之前你什么都得不到……这不是预期的

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐