【发布时间】:2019-11-05 08:49:27
【问题描述】:
所以这是我的问题,
我正在尝试使用 Python 的 subprocess 模块编写一个运行另一个进程的简单程序,并且我想捕获该进程的实时输出。
我知道可以这样做:
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE)
for line in iter(proc.stdout.readline, ""):
line = line.rstrip()
if line != "":
print(line)
问题是,该过程可能会生成带有回车符\r 的输出,我想在我的程序中模拟这种行为。
如果我在Popen 中使用universal_newlines 标志,那么我可以捕获由回车生成的输出,但我不知道它是这样的,我只能“定期”打印它换行。我想避免这种情况,因为这可能会产生很多输出。
我的问题基本上是我是否可以像\n 一样捕捉\r 输出,但将其与实际\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,这不起作用。
【问题讨论】:
-
IMO,如果您想将换行符视为有趣的数据,那么您不应该使用基于行的输入。您应该读取和缓冲数据块,然后自己扫描和处理
\r和\n字符。您很有可能使用readline()得到您想要的,但我认为这会使您的解决方案过于复杂。 -
@JohnHennig 您链接到的问题正是我写的我现在正在做的事情。问题是,确实,我不想要通用换行符。我希望我的程序能够像我运行的程序一样使用回车。问题是
readline一直读到遇到换行符 -
@Steve 这就是我尝试做的,逐个字符地阅读。从 PyCharm 运行时它运行正常,但由于某种原因,它在从终端运行时无法正常工作。虽然无法弄清楚问题是什么
-
@Zionsof,如果你在 PyCharm 和终端中得到不同的行为,那是一个明显的问题,如果我是你,我会解决或至少想了解。控制台输入是可能必须容忍行为差异的少数领域之一。也许你可以在这里详细说明一些代码,我们可以帮助你。
-
@Davis 我猜 stderr 上有一个进度指示器,它通过在更新状态之前打印回车来覆盖前一行来更新。输出中必须没有换行符才能正常工作。
标签: python subprocess