我暂时改变了我的代理配置,以便在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',)))",),)
那很好。另一方面,我想使用子进程模块捕获这些错误消息,如下面的代码。
test.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())
虽然我可以&#34;看到&#34;运行cmd.exe
时test.py
上的完整消息,
但记录器只捕获如下...
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似乎与我的问题非常接近,但没有财富。任何建议对我都非常有帮助。提前谢谢。
答案 0 :(得分:2)
最有可能的原因是你只将stdout重定向到管道。您还必须重定向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上你需要运行一个额外的线程,这样你就可以同时读取这两个管道。
如果你在单个线程中执行它并在读取stdout时阻塞大量数据被转储到stderr管道,你可能会永远挂起,因为stderr管道缓冲区会填满并阻塞写入stderr的进程,意味着两个进程都会死锁,一个等待stderr缓冲区变为空,另一个进程则stdout缓冲区填满一行输出。
在Linux上,您可以使用select调用来选择具有可读取数据的管道,但这仅适用于Windows上的套接字。
另一个不需要线程的解决方案可能是将命令的stderr重定向到stdout,然后再将它传递给你的python进程。您将无法分辨哪些字节最初转到stdout以及哪些字节转到stderr,但根据您的使用情况,这可能并不重要。