当前位置:  开发笔记 > 编程语言 > 正文

如何从Python异步运行外部命令?

如何解决《如何从Python异步运行外部命令?》经验,为你挑选了5个好方法。

我需要从Python脚本异步运行shell命令.通过这个我的意思是我希望我的Python脚本在外部命令关闭时继续运行并执行它需要做的任何事情.

我看过这篇文章:

在Python中调用外部命令

然后我os.system()去做了一些测试,看起来我会&在命令结束时使用它来完成工作,这样我就不必等待它返回了.我想知道的是,这是否是实现这一目标的正确方法?我试过commands.call()但它对我不起作用,因为它阻止了外部命令.

如果使用os.system()这个是可取的,或者我应该尝试其他路线,请告诉我.



1> Ali Afshar..:

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上发送数据,并等待它终止.


然而,communic()和wait()是阻塞操作.你不会像OP一样并行化命令,如果你使用它们就会问.
您还可以使用poll()来检查子进程是否已终止,或使用wait()等待它终止.

2> cdleary..:

如果要并行运行多个进程,然后在产生结果时处理它们,可以使用如下所示的轮询:

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第一个正在运行的进程并且结果运行时间过长,那么当您可以处理其结果时,其他正在运行的进程将处于空闲状态.


使用`['/ usr/bin/my_cmd',' - i',path]`而不是`['/ usr/bin/my_cmd',' - i%s'%path]
@Tino这取决于你如何定义忙等待.请参阅[忙等待和轮询之间有什么区别?](http://stackoverflow.com/questions/10594426/)

3> S.Lott..:

我想知道的是,如果[os.system()]是完成这样的事情的正确方法吗?

os.system()是不正确的方法.这就是每个人都说使用的原因subprocess.

有关更多信息,请阅读http://docs.python.org/library/os.html#os.system

子流程模块提供了更强大的工具来生成新流程并检索其结果; 使用该模块比使用此功能更可取.使用子进程模块.请特别检查"使用子过程模块替换旧函数"部分.



4> Noah..:

我在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



5> Gabe..:

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.

推荐阅读
凹凸曼00威威_694
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有