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

2024-04-18 09:14:11 发布

您现在位置:Python中文网/ 问答频道 /正文

我需要从Python脚本异步运行shell命令。我的意思是,我希望我的Python脚本在外部命令关闭时继续运行,并执行它需要执行的任何操作。

我看了这篇文章:

Calling an external command in Python

然后我离开并做了一些测试,看起来只要我在命令的末尾使用&就可以完成任务,这样我就不必等待它返回。我想知道的是这是否是完成这件事的正确方法?我试过commands.call()但它对我不起作用,因为它阻塞了外部命令。

请告诉我是否建议使用os.system()进行此操作,或者我是否应该尝试其他路径。


Tags: 方法in命令脚本外部命令anshellcall
3条回答

我想知道的是,这个[os.system()]是否是实现这一点的正确方法?

不,os.system()不是正确的方式。这就是为什么每个人都说要用subprocess

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

The subprocess module provides more powerful facilities for spawning new processes and retrieving their results; using that module is preferable to using this function. Use the subprocess module. Check especially the Replacing Older Functions with the subprocess Module section.

subprocess.Popen做你想做的事。

from subprocess import Popen
p = Popen(['watch', 'ls']) # something long running
# ... do other stuff while subprocess is running
p.terminate()

(编辑以完成注释中的答案)

Popen实例可以执行其他各种操作,比如可以^{}查看它是否仍在运行,也可以^{}使用它在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,结果发现运行时间最长,则其他运行的进程在您可以处理其结果时将一直处于空闲状态。

相关问题 更多 >