我正在从Python执行Shell脚本,到目前为止,它工作正常。但是我坚持一件事。
在我的Unix机器上,我正在使用&
这样的后台执行一个命令。此命令将启动我的应用服务器-
david@machineA:/opt/kml$ /opt/kml/bin/kml_http --config=/opt/kml/config/httpd.conf.dev &
现在,我需要从Python脚本中执行相同的操作,但是一旦它执行了我的命令,它就永远不会消失else block
并且永远不会打印出来execute_steps::Successful
,它只是挂在那上面。
proc = subprocess.Popen("/opt/kml/bin/kml_http --config=/opt/kml/config/httpd.conf.dev &", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, executable='/bin/bash')
if proc.returncode != 0:
logger.error("execute_steps::Errors while executing the shell script: %s" % stderr)
sleep(0.05) # delay for 50 ms
else:
logger.info("execute_steps::Successful: %s" % stdout)
我在这里做错什么了吗?我想execute_steps::Successful
在后台执行shell脚本后打印出来。
所有其他命令都可以正常运行,但是只有我尝试在后台运行的命令无法正常运行。
这里发生了几件事情。
首先,您要在后台启动Shell,然后告诉该Shell在后台运行程序。我不知道您为什么认为两者都需要,但现在让我们忽略它。事实上,通过增加executable='/bin/bash'
之上shell=True
,你实际上是试图运行shell运行shell来在后台运行程序,但实际上并没有那么回事。*
其次,您正在使用PIPE
过程的输出和错误,但没有读取它们。这可能导致孩子陷入僵局。如果您不想要输出,请使用DEVNULL
,而不是PIPE
。如果您希望输出自行处理,请使用proc.communicate()
。**或使用更高级别的函数,例如check_output
。如果只希望它与您自己的输出混合在一起,则不要使用这些参数。
*如果使用shell是因为它kml_http
是必须由执行的不可执行脚本/bin/bash
,则不要shell=True
为此使用或executable
,只需/bin/bash
在命令行中输入第一个参数,然后/opt/kml/bin/kml_http
输入第二个即可。但这似乎不太可能。为什么要在bin
目录中安装不可执行的内容?
**或者,您可以从proc.stdout
和显式读取它proc.stderr
,但这变得更加复杂。
无论如何,在后台执行某些操作的全部目的在于它始终在后台运行,而脚本始终在前台运行。因此,您要returncode
在完成之前检查它,然后继续进行代码中的下一个操作,而再也不会回来。
似乎您想等待它完成。在这种情况下,请不要在后台运行它-使用proc.wait
,或者仅使用subprocess.call()
而不是创建Popen
对象。&
当然也不要使用。当我们使用它时,请不要使用外壳程序:
retcode = subprocess.call(["/opt/kml/bin/kml_http",
"--config=/opt/kml/config/httpd.conf.dev"],
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
if retcode != 0:
# etc.
现在,您将无法完成该if
语句kml_http
。
如果您想等待它完成,但同时又继续做其他事情,那么您将尝试在程序中一次完成两件事,这意味着您需要一个线程来进行等待:
def run_kml_http():
retcode = subprocess.call(["/opt/kml/bin/kml_http",
"--config=/opt/kml/config/httpd.conf.dev"],
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
if retcode != 0:
# etc.
t = threading.Thread(target=run_kml_http)
t.start()
# Now you can do other stuff in the main thread, and the background thread will
# wait around until kml_http is finished and execute the `if` statement whenever
# that happens
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句