【问题标题】:Execute subprocess that prints to stdout, wait for text and then continue execution of the main script执行打印到标准输出的子进程,等待文本,然后继续执行主脚本
【发布时间】:2020-05-21 15:36:07
【问题描述】:

在 Python 3 中,我该怎么做:

  1. 执行一个进程并将其标准输出打印到标准输出,
  2. 监控标准输出以等待一些文本,并且
  3. 在找到文本后继续执行我的 Python 程序,不要终止进程,也不要停止将其打印到标准输出。

live output from subprocess command 不是重复的,因为那里的所有答案都不允许您的 Python 代码继续并且仍然打印进程的标准输出。

我想解决方案将涉及某种线程、协程或任务。

【问题讨论】:

标签: python subprocess


【解决方案1】:

一个相对简单的方法是在完成处理后启动一个新线程将进程的标准输出复制到 Python 的标准输出。这是一个运行webpack-dev-server 并从中抓取 URL 的示例(未实际实现):

#!/usr/bin/env python3

import subprocess
import sys
import os
from threading import Thread

from typing import IO

def pipe(a: IO[bytes], b: IO[bytes]):
  for x in a:
    b.write(x)
    b.flush()


process = subprocess.Popen(
  [
    "node_modules/.bin/webpack-dev-server",
    # Note that I had to add --colour because for some reason
    # webpack-dev-server detects stdout as supporting colour,
    # but not stderr.
    "--color",
    # This prints a progress bar using ANSI escape characters
    # which works too!
    "--progress",
  ],
  cwd=".",
  env=dict(os.environ, NODE_ENV="development"),
  stdout=subprocess.PIPE,
)

for line in process.stdout:
  sys.stdout.buffer.write(line)
  # Flush is necessary otherwise stdout will buffer more
  # than one line.
  sys.stdout.buffer.flush()

  # Process the text however you want.
  if b"Project is running at" in line:
    print("Server started at address ??")
    break

# Start a thread to do the pipe copying.
thread = Thread(target=pipe, args=(process.stdout, sys.stdout.buffer))
thread.start()

print("Now we can do other stuff and the process will continue to print to stdout")

请注意,我没有考虑过适当的清理——退出线程、关闭文件等。

【讨论】:

    猜你喜欢
    • 2015-11-14
    • 1970-01-01
    • 2018-05-19
    • 2020-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多