【问题标题】:Capturing subprocess in console and python在控制台和 python 中捕获子进程
【发布时间】:2021-09-05 04:08:46
【问题描述】:

我正在尝试使用 python 执行一些 bash 命令。我想向用户显示命令的实时输出并捕获它。
一个示例是这样的

import subporcess

# This will store output in result but print nothing to terminal
result = subprocess.run(['ls', '-lh'], check=True, universal_newlines=True, stdout=subprocess.PIPE)
print(result.stdout) # STD OUTPUT
# This will print everything to terminal result will be empty
result = subprocess.run(['ls', '-lh'], check=True, universal_newlines=True)
print(result.stdout) # OUTPUT = None

【问题讨论】:

  • 您可以使用.check_output 而不是.run。看看documentation
  • 如果您查看函数参数,您会发现没有 stdout 选项。即 checkout 只会将输出返回到 python,但不会在控制台上打印任何内容。
  • 你可以自己 print 这个到控制台..
  • 是的.. 但是我试图运行的过程大约需要30 min 直到那时用户会认为程序已经死了。
  • 在这种情况下,您可以继承 subprocess.PIPE 并使其同时在两个地方写入输出。

标签: python subprocess


【解决方案1】:

这是一种可能,它会从长时间运行的进程中收集输出行,在运行时将它们写入终端,并在进程退出时将它们全部返回。

它返回一个输出行列表,而不是check_outputrun 将返回的完整文本块,但这很容易改变。根据您期望的输出量,IO 缓冲区可能会更有效。

import subprocess
import sys

def capture_and_echo_stdout(cmd):
    """ Start a subprocess and write its stdout to stdout of this process.     
    Capture and return stdout lines as a list. """
    proc = subprocess.Popen(cmd, stdout=subprocess.PIPE)
    stdout_lines = []
    for line in proc.stdout:
        sys.stdout.write(line.decode())
        stdout_lines.append(line)
    proc.communicate()
    # Roughly equivalent to check=True
    if proc.returncode:
        raise subprocess.CalledProcessError(proc.returncode, cmd)
    return stdout_lines

这个答案中有几个类似的选项(尽管更多的重点是写入多个文件,如 unix tee):How to replicate tee behavior in Python when using subprocess?

【讨论】:

  • 谢谢.. 这是我考虑的选项之一。但是run 非常稳定,涵盖了一些我在使用 Popen 时无法处理的极端情况。但是感谢您的出色回答。
猜你喜欢
  • 2021-05-06
  • 2014-08-15
  • 1970-01-01
  • 1970-01-01
  • 2020-05-23
  • 1970-01-01
  • 2016-07-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多