设置
我有一个小的Runner
程序,它在sys.stderr
中打印一些信息(对于日志、未处理的异常等等)。和sys.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
程序,它在新窗口中用subprocess.Popen
启动Runner
并打印它的输出:
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
我需要并行运行几个Runners
,并等待它们最近,但是subprocess.check_input
或subprocess.run
不允许这样做(或者我错了吗?)
为什么是新窗户?
我想要为他们的个人窗口中的每一个Runner
单独看到指纹。
我想要的
我希望重定向stderr
only ,并将stdout
保持在打开的窗口中,因此Main
程序只会从子进程输出错误:
[This is text #1 to STDERR
This is text #2 to STDERR
This is text #3 to STDERR
]
这对于调试新的Runner
功能非常有用.
我试过的
当subprocess.Popen
具有stderr=subprocess.PIPE
param和stdout=None
(默认)时,stdout
阻塞:
没有显示在None
窗口中的
proc.communicate
返回Runner
所以stdout
指纹就消失了..。我甚至尝试将sys.stdout
传递给stdout=
param (输出不是在窗口中,而是在当前控制台中),但是它会引发Bad file descriptor
错误:
[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
__)
需要帮助..。
发布于 2022-08-04 09:54:24
这里是一个满足‘我想要什么’部分的要求的解决方案:
main.py
import subprocess
command = ["python", "runner.py"]
process = subprocess.Popen(command, shell=False, text=True, stderr=subprocess.PIPE, creationflags=subprocess.CREATE_NEW_CONSOLE)
process.wait()
stderr = process.stderr.read()
print(stderr, end="")
runner.py
包含问题中提到的代码。
参数shell=False
用于直接运行python runner.py
(即不作为shell命令),text=True
使subprocess
在文本模式(而不是二进制模式)中打开process.stderr
。
运行此操作时,发送给stdout的runner.py
的输出将出现在新窗口中,而发送给stderr的输出将在变量stderr
中捕获(并且还会打印在main.py
的窗口中)。
如果runner.py
的输出应在生成时立即处理(即无需等待进程完成),则可以使用以下代码:
main.py
import subprocess
command = ["python", "runner.py"]
process = subprocess.Popen(command, shell=False, text=True, bufsize=1, stderr=subprocess.PIPE, creationflags=subprocess.CREATE_NEW_CONSOLE)
stderr = ""
while (True):
line = process.stderr.readline()
if (line == ""): break # EOF
stderr += line
print(line, end="")
runner.py
(修改以说明差异):
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(1)
参数bufsize=1
用于从runner.py
的stderr获得行缓冲输出。
在Windows 1021H2+Python3.10.4上成功测试。
https://stackoverflow.com/questions/72913044
复制相似问题