这是我的问题,
我正在尝试制作一个简单的程序,该程序使用Python的subprocess
模块运行另一个进程,我想捕获该进程的实时输出。
我知道可以这样做:
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE)
for line in iter(proc.stdout.readline, ""):
line = line.rstrip()
if line != "":
print(line)
问题是,该进程可能生成带有回车符\r
的输出,并且我想在程序中模拟该行为。
如果我在universal_newlines
中使用Popen
标志,那么我可以捕获用回车符生成的输出,但是我不知道是这样,所以我只能打印用换行符“定期”进行。我想避免这种情况,因为这可能会产生很多输出。
我的问题基本上是,我是否可以像\r
一样捕获\n
输出,但将其与实际\n
输出区分
编辑
这是我尝试过的一些简化代码:
文件download.py
:
import subprocess
try:
subprocess.check_call(
[
"aws",
"s3",
"cp",
"S3_LINK",
"TARGET",
]
)
except subprocess.CalledProcessError as err:
print(err)
raise SystemExit(1)
文件process_runner.py
:
import os
import sys
import subprocess
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE)
for char in iter(lambda: proc.stdout.read(1), ""):
sys.stdout.write(char)
download
中的代码使用aws s3 cp
,它返回下载进度的回车符。我想在程序process_runner
中模拟输出的这种行为,该程序接收download
的输出。
起初,我尝试迭代readline
而不是read(1)
。由于CR被忽略,因此无法正常工作。
答案 0 :(得分:2)
一种可能的方法是通过既不指定encoding
也不指定error
,当然也不要指定universal_newline
来使用Popen的二进制接口。然后,我们可以在二进制流中使用TextIOWrapper
,与newline=''
一起使用。因为TextIOWrapper的文档说:
...如果换行符是
None
...如果它是''
,则启用通用换行符模式,但行尾未翻译后返回给呼叫者
(符合PEP 3116)
您的原始代码可以更改为:
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE)
out = io.TextIOWrapper(proc.stdout, newline='')
for line in out:
# line is delimited with the universal newline convention and actually contains
# the original end of line, be it a raw \r, \n of the pair \r\n
...