Python subprocess.popen:重定向`s stderr`仅保留``stdout''
设置
我有一个小Runner
程序,该程序在sys.stderr
中打印一些信息(对于日志,未手动异常等)和sys.ss.stdout
(有关程序的一些有用信息,可能与用户或SMTH互动):
import sys
import time
for i in range(1, 4):
sys.stdout.write(f"This is text #{i} to STDOUT\n")
sys.stderr.write(f"This is text #{i} to STDERR\n")
time.sleep(5)
我有一些main
程序,在新窗口 Runner >与subprocess.popen
并打印其输出:
import subprocess
cmd = "python runner.py"
proc = subprocess.Popen(cmd,
stdout=subprocess.PIPE, # Problem line
stderr=subprocess.PIPE,
creationflags=subprocess.CREATE_NEW_CONSOLE
)
proc.wait()
out, err = proc.communicate()
if out:
print(f"[{out.decode('utf-8')}]")
if err:
print(f"[{err.decode('utf-8')}]")
因此,结果输出是:
[This is text #1 to STDOUT
This is text #2 to STDOUT
This is text #3 to STDOUT
]
[This is text #1 to STDERR
This is text #2 to STDERR
This is text #3 to STDERR
]
为什么popen
?
我需要运行几个跑步者
最近等待它们,但是subprocess.check_input
或subprocess.run
不允许(或者我错了) ??)
为什么要新窗口?
我想在他们的个人窗口中分别查看每个runner
我想要
重定向stderr
唯一的,并保留stdout < /code>在打开的窗口中,因此
main
程序只会从子过程中输出错误:
[This is text #1 to STDERR
This is text #2 to STDERR
This is text #3 to STDERR
]
这对于调试新Runner
的功能非常有用...
我尝试了什么
什么时候subprocess.popen
has stderr = subprocess.pipe
param and stdout = none
(默认),stdout
是阻止:
- 它没有在
Runner
窗口 - 和
proc.communate
返回无
中显示,因此stdout
打印只是消失了...我什至尝试通过sys.stdout
to stdout =
param(用于窗口中的输出,而是在当前控制台中),但是它抛出了不良文件描述符
错误:
[Traceback (most recent call last):
File "C:\Users\kirin\source\repos\python_tests\runner.py", line 5, in <module>
sys.stdout.write(f"This is text #{i} to STDOUT\n")
OSError: [Errno 9] Bad file descriptor
Exception ignored in: <_io.TextIOWrapper name='<stdout>' mode='w' encoding='cp1251'>
OSError: [Errno 9] Bad file descriptor
]
(顺便说一句,此打印是从Runner
main )成功地重定向
的。
Setup
I have a little Runner
program, that prints some info in sys.stderr
(for logs, unhandled exceptions and etc.) and sys.stdout
(some usefull info about program, maybe interaction with user or smth):
import sys
import time
for i in range(1, 4):
sys.stdout.write(f"This is text #{i} to STDOUT\n")
sys.stderr.write(f"This is text #{i} to STDERR\n")
time.sleep(5)
And I have some Main
program, that starts Runner
in the new window with subprocess.Popen
and prints it's output:
import subprocess
cmd = "python runner.py"
proc = subprocess.Popen(cmd,
stdout=subprocess.PIPE, # Problem line
stderr=subprocess.PIPE,
creationflags=subprocess.CREATE_NEW_CONSOLE
)
proc.wait()
out, err = proc.communicate()
if out:
print(f"[{out.decode('utf-8')}]")
if err:
print(f"[{err.decode('utf-8')}]")
So the resulting output is:
[This is text #1 to STDOUT
This is text #2 to STDOUT
This is text #3 to STDOUT
]
[This is text #1 to STDERR
This is text #2 to STDERR
This is text #3 to STDERR
]
Why Popen
?
I need to run several Runners
parallely and wait them lately, but subprocess.check_input
or subprocess.run
does not allow that (or am I wrong??)
Why new window?
I want to see prints separetely for every Runner
in their personal windows
What I want
I want to redirect stderr
only and keep stdout
in opened window, so the Main
program will only output errors from subprocess:
[This is text #1 to STDERR
This is text #2 to STDERR
This is text #3 to STDERR
]
That will be very usefull for debugging new Runner
's features...
What I tried
When subprocess.Popen
has stderr=subprocess.PIPE
param and stdout=None
(default), stdout
is blocking:
- it doesn't show in the
Runner
window - and
proc.communicate
returnsNone
So the stdout
prints just disappeared... I tried even pass sys.stdout
to stdout=
param (for output not in window, but in current console), but it throws Bad file descriptor
error:
[Traceback (most recent call last):
File "C:\Users\kirin\source\repos\python_tests\runner.py", line 5, in <module>
sys.stdout.write(f"This is text #{i} to STDOUT\n")
OSError: [Errno 9] Bad file descriptor
Exception ignored in: <_io.TextIOWrapper name='<stdout>' mode='w' encoding='cp1251'>
OSError: [Errno 9] Bad file descriptor
]
(btw, this print was succesfully redirected from Runner
to Main
)
Need help...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这是一个满足“我想要的”部分要求的解决方案:
main.py
:runner.py.py
包含代码问题。参数
shell = false
用于直接运行python runner.py
(即不作为shell命令),text = true
make> makesubprocess
openprocess.stderr
在文本模式下(而不是二进制模式)。运行此操作时,从
runner.py
发送到 stdout 的输出出现在新窗口中,而输出发送到 stderr 则在变量中捕获到 stderr stderr
(也印在main.py
的窗口中)。如果
runner.py
的输出应在生产时立即处理(即不等待该过程首先完成),则可以使用以下代码:main.py.py :
runner.py
(修改以说明差异):参数
bufsize = 1
在此使用,从runner.py 's stderr 。
在Windows 10 21H2 + Python 3.10.4上成功测试。
Here is a solution that meets the requirements of the 'What I want' section:
main.py
:runner.py
contains the code mentioned in the question.Argument
shell=False
is used to runpython runner.py
directly (i.e. not as a shell command),text=True
makessubprocess
openprocess.stderr
in text mode (instead of binary mode).When running this, output from
runner.py
sent to stdout appears in the new window while output sent to stderr is captured in variablestderr
(and also printed inmain.py
's window).If
runner.py
's output shall be processed right away as it is produced (i.e. without waiting for the process to finish first), the following code may be used:main.py
:runner.py
(modified to illustrate the difference):Argument
bufsize=1
is used here to get line-buffered output fromrunner.py
's stderr.Successfully tested on Windows 10 21H2 + Python 3.10.4.