尝试调用Shell命令异步时,Python错误引发NotImplementedError

时间:2020-02-27 11:27:02

标签: python asynchronous

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

2 个答案:

答案 0 :(得分:1)

https://github.com/python/cpython/blob/master/Lib/asyncio/base_events.py#L493

这是一项计划的功能,但尚未实现。它将在将来运行,但是当前版本不支持它。

我浏览了其他分支,但都没有实现。子流程模块(https://docs.python.org/3/library/subprocess.html)是众所周知的,并且asyncio对它的支持尚未完成。端点已定义,但截至目前仍无法使用。

答案 1 :(得分:0)

在文档中对其进行了解释:

Python 3.7

https://docs.python.org/3.7/library/asyncio-platforms.html#asyncio-windows-subprocess

Windows上的

SelectorEventLoop不支持子过程。在Windows上, 应该改用ProactorEventLoop:

class Singleton
{
private:
  std::atomic<bool> initialised;
  Singleton()
  : initialised(false)
  {
  }

  Singleton& instanceImpl()
  {
    static Singleton singleton;
    return singleton;
  }

public:
  void Init(int foo)
  {
    auto& instance = instanceImpl();
    if (instance.initialised) throw std::runtime_error("already inited");
    instance.initialised = true;
  }

  Singleton& getInstance()
  {
    auto& instance = instanceImpl();
    if (!instance.initialised) throw std::runtime_error("not inited");
    return instance;
  }
};

Python 3.8

Windows上的默认事件循环现在是ProactorEventLoop。