我需要从Python脚本异步运行shell命令.通过这个我的意思是我希望我的Python脚本在外部命令关闭时继续运行并执行它需要做的任何事情.
我看过这篇文章:
在Python中调用外部命令
然后我os.system()
去做了一些测试,看起来我会&
在命令结束时使用它来完成工作,这样我就不必等待它返回了.我想知道的是,这是否是实现这一目标的正确方法?我试过commands.call()
但它对我不起作用,因为它阻止了外部命令.
如果使用os.system()
这个是可取的,或者我应该尝试其他路线,请告诉我.
subprocess.Popen正是你想做的.
from subprocess import Popen p = Popen(['watch', 'ls']) # something long running # ... do other stuff while subprocess is running p.terminate()
(编辑以完成评论的答案)
Popen实例可以执行各种其他操作,就像poll()
它可以查看它是否仍在运行,并且您可以communicate()
使用它在stdin上发送数据,并等待它终止.
如果要并行运行多个进程,然后在产生结果时处理它们,可以使用如下所示的轮询:
from subprocess import Popen, PIPE import time running_procs = [ Popen(['/usr/bin/my_cmd', '-i %s' % path], stdout=PIPE, stderr=PIPE) for path in '/tmp/file0 /tmp/file1 /tmp/file2'.split()] while running_procs: for proc in running_procs: retcode = proc.poll() if retcode is not None: # Process finished. running_procs.remove(proc) break else: # No process is done, wait a bit and check again. time.sleep(.1) continue # Here, `proc` has finished with return code `retcode` if retcode != 0: """Error handling.""" handle_results(proc.stdout)
那里的控制流程有点复杂,因为我试图让它变小 - 你可以根据自己的喜好进行重构.:-)
这具有首先为早期完成请求提供服务的优点.如果您调用communicate
第一个正在运行的进程并且结果运行时间过长,那么当您可以处理其结果时,其他正在运行的进程将处于空闲状态.
我想知道的是,如果[os.system()]是完成这样的事情的正确方法吗?
号 os.system()
是不正确的方法.这就是每个人都说使用的原因subprocess
.
有关更多信息,请阅读http://docs.python.org/library/os.html#os.system
子流程模块提供了更强大的工具来生成新流程并检索其结果; 使用该模块比使用此功能更可取.使用子进程模块.请特别检查"使用子过程模块替换旧函数"部分.
我在asyncproc模块上取得了很大的成功,它可以很好地处理来自进程的输出.例如:
import os from asynproc import Process myProc = Process("myprogram.app") while True: # check to see if process has ended poll = myProc.wait(os.WNOHANG) if poll is not None: break # print any new output out = myProc.read() if out != "": print out
Using pexpect [ http://www.noah.org/wiki/Pexpect ] with non-blocking readlines is another way to do this. Pexpect solves the deadlock problems, allows you to easily run the processes in the background, and gives easy ways to have callbacks when your process spits out predefined strings, and generally makes interacting with the process much easier.