gpt4 book ai didi

python - 从 stdout 或 stderr 获取子进程的消息

转载 作者:行者123 更新时间:2023-12-01 02:36:34 24 4
gpt4 key购买 nike

我暂时更改了代理配置,以在 cmd.exe 上引发以下错误...

C:\Users\su79e\abs_engine>C:/ProgramData/Anaconda3/Scripts/conda create --name test python=3.5

Fetching package metadata ...

# After 5~10 seconds

CondaHTTPError: HTTP None None for url <https://repo.continuum.io/pkgs/free/win-64/repodata.json.bz2>
Elapsed: None

An HTTP error occurred when trying to retrieve this URL.
HTTP errors are often intermittent, and a simple retry will get you on your way.
ProxyError(MaxRetryError("HTTPSConnectionPool(host='repo.continuum.io', port=443): Max retries exceeded with url: /pkgs/free/win-64/repodata.json.bz2 (Caused by ProxyError('Cannot connect to proxy.', NewConnectionError('<requests.packages.urllib3.connection.VerifiedHTTPSConnection object at 0x000001DBCA650AC8>: Failed to establish a new connection: [Errno 11001] getaddrinfo failed',)))",),)

嗯,这很好。另一方面,我想使用 subprocess 模块捕获这些错误消息,如下面的代码。

测试.py

with subprocess.Popen("C:/ProgramData/Anaconda3/Scripts/conda create -y --name test python=3.5",
universal_newlines=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE) as proc:
# out, err = proc.communicate()
# logger.info(out)
# logger.info(err)
while proc.poll() is None:
logger.info(proc.stdout.readline())
# logger.info(proc.stderr.readline())

虽然我可以在运行 test.py 时“看到”cmd.exe 上的完整消息,但记录器仅捕获如下所示...

test.py:104 - INFO - 2017-09-11 22:16:29,858 - Fetching package metadata ...
test.py:104 - INFO - 2017-09-11 22:16:29,858 -

尽管有 while 循环,它只捕获错误之前的消息。我错过了什么吗?我已经在 Stackoverflow 和 this 上检查了很多答案。似乎与我的问题非常接近,但没有财富。任何建议都会对我非常有帮助。预先感谢您。

最佳答案

这很可能是因为您只将标准输出重定向到管道。您还必须重定向 stderr(请参阅 Popen 的文档):

subprocess.Popen("C:/ProgramData/Anaconda3/Scripts/conda create -y --
name test python=3.5", universal_newlines=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE) as proc:

(这里缺少 stderr=subprocess.PIPE)

但是,如果您将 stdout 和 stderr 都重定向到一个管道,则在 Windows 上您需要运行一个额外的线程,以便可以同时从两个管道中读取数据。

如果您在单个线程中执行此操作,并在大量数据转储到 stderr 管道时阻止读取 stdout,则可能会永远挂起,因为 stderr 管道缓冲区会填满并阻止写入 stderr 的进程,这意味着两个进程都将陷入死锁,一个进程等待 stderr 缓冲区变空,另一个进程等待 stdout 缓冲区填满一行输出。

在 Linux 上,您可以使用 select 调用来选择具有可供读取数据的管道,但这仅适用于 Windows 上的套接字。

另一个不需要线程的解决方案可能是将命令的 stderr 重定向到 stdout,然后再将其通过管道传输到 python 进程。您将无法分辨哪些字节最初发送到 stdout,哪些字节发送到 stderr,但根据您的用例,了解这一点可能并不重要。

关于python - 从 stdout 或 stderr 获取子进程的消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46157754/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com