当使用asyncio subprocess尝试调用shell命令时,Python会引发NotImplementedError异常。

3

我刚开始学习Python编程。我想并行调用几个Shell命令,并将它们的结果累积到一个单一的数组中,就像JavaScript的promise.all()方法一样。

我在Python中有以下代码:

import asyncio
import os


commands = [
    'netstat -n | findstr 55601',
    'dir | findstr portMonitoring.py',
    'ssh 10.6.100.192 netstat'
]

async def job(cmd):
    # await asyncio.sleep(1)
    # return "HEE"
    # return os.popen(cmd).read()
    process = await asyncio.create_subprocess_exec(
        cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE
    )

    return await process.communicate()



async def main():
    jobs = [job(cmd) for cmd in commands]
    done, pending = await asyncio.wait(jobs, return_when=asyncio.FIRST_COMPLETED)
    folders = []
    [folders.append(d.result()) for d in done]
    print("RESULT:", folders)

asyncio.run(main())

我遇到了以下错误:
Traceback (most recent call last):
  File "test.py", line 16, in job
    cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE
  File "C:\DEV\Python3.7.4\lib\asyncio\subprocess.py", line 217, in create_subprocess_exec
    stderr=stderr, **kwds)
  File "C:\DEV\Python3.7.4\lib\asyncio\base_events.py", line 1529, in subprocess_exec
    bufsize, **kwargs)
  File "C:\DEV\Python3.7.4\lib\asyncio\base_events.py", line 458, in _make_subprocess_transport
    raise NotImplementedError
NotImplementedError

我会尝试安装Python 3.8(在虚拟环境或通过conda),并尝试使用它。我猜你正在尝试使用一个在3.7.4中尚未实现的功能。 - dzang
我现在手头没有3.7,无法直接重现你的错误。但是这是我发现的:将你的代码粘贴到https://www.python.org/shell/ 的3.8控制台中会显示不同的错误,但不会显示RESULT行。然而,如果我将create_subprocess_exec替换为create_subprocess_shell,我也会得到错误,但现在可以看到RESULT行了。你已经尝试过了吗?文档对我来说不是很清楚应该使用哪一个... - Michael H.
3个回答

1

1


0
如果你正在使用Jupyter,因此无法切换到ProactorEventLoop,请参考:https://dev59.com/v1cP5IYBdhLWcg3wRoEI#76981596 这里是运行Docker进程的示例:
import asyncio
import subprocess

async def run_docker(args: list[str]):
    def run():
        process = subprocess.Popen(
            ["docker"]
            + args,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            text=True,
        )

        stdout, stderr = process.communicate()

        if stderr:
            raise Exception(stderr)

        return stdout

    return await asyncio.to_thread(run)

请审查[答案]。 - ChrisGPT was on strike

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接