【问题标题】:How to get realtime Python subprocess output?如何获取实时 Python 子进程输出?
【发布时间】:2021-01-18 08:43:37
【问题描述】:

我尝试使用 shell 命令运行的程序每秒输出一个单词。我正在尝试在 Python 脚本中执行一个 shell 命令,并在输出的每个单词上获得实时输出。我在网上找到的所有其他解决方案实际上并没有打印实时输出,而是一次打印一条完成的行。我想获得 real 实时输出,其中每个单词都是实时打印出来的,而不是每一行。这是我尝试过的代码:

cmd=['slowprogram','-m', '15', '-l', '50']
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, bufsize=1)
for line in iter(p.stdout.readline, b''):
    print(line),
p.stdout.close()
p.wait()

它等到一行完成并打印它。有没有办法实时更新并打印一行中的每个单词?

更新:

p = subprocess.Popen(cmd, stdout=subprocess.PIPE, bufsize=1)
for line in iter(p.stdout.readline, b''):
    for word in iter(line):
      print(word)
p.stdout.close()
p.wait()

由于某种原因返回一堆数字...:

111
117
108
100
32
104
97
118
101
32
115
97

如何从行中获取每个单词?

【问题讨论】:

  • p.stdout 是一个io.BytesIO 对象;从语法上讲,您可以随意读取它,就好像它是一个文件一样。您可能还想根据需要查看 bufsize 参数。
  • @YiFei 我尝试迭代一行中的每个单词,但输出出乎意料。我已经更新了我的问题,你能看看吗?
  • @YiFei 我还是想不通。您能否展示如何实时读取 p.stdout?

标签: python python-3.x shell subprocess


【解决方案1】:

这是一种方法,它在 Linux shell 中对我有用。它使用一个无缓冲的 IO 对象并一次打印出一个字符。我很确定有更好的方法,因为我不是subprocess 或事件处理方面的专家。您可能还想查看asyncio

with subprocess.Popen(cmd, stdout=subprocess.PIPE, bufsize=0) as p:
    char = p.stdout.read(1)
    while char != b'':
        print(char.decode('UTF-8'), end='', flush=True)
        char = p.stdout.read(1)

【讨论】:

  • 如何将输出保存到每个单词前没有'b'的数组?当我将 char 变量附加到数组时,每个单词之前都会显示“b”。
  • 重新表述:如何将整个输出保存到数组中?
  • 一点上下文:Python 处理两种类型的“字符串”:字节字符串和“文本”字符串。我们从Popen 捕获的是一个字节字符串,因此是b。现在可以通过decoding将字节字符串转换为文本字符串,并通过编码向后转换。
  • 我明白了。当我尝试将解码的字符保存到一个数组时,我的单词由于某种原因而分裂了。 'Hello' 可能会变成 'hel' 和 'lo'。有没有办法在不重新运行整个命令的情况下保存整个输出?
  • 假设你有一个列表(或任何可迭代的)L = ['hel', 'lo'],你可以使用''.join(L)。但是根据您的需要,您也可以从头开始保存并附加到字符串。
猜你喜欢
  • 2015-06-08
  • 2022-06-19
  • 1970-01-01
  • 2010-10-22
  • 2021-04-15
  • 1970-01-01
相关资源
最近更新 更多