Featured image of post 『 Python 』Subprocess.Popen 监控控制台输出

『 Python 』Subprocess.Popen 监控控制台输出

问题描述

  1. 在 Python 代码中编译可执行文件,需要监控执行过程及运行结果,当前场景等效为捕获控制台的特征信息的“打印情况”;
  2. 编译程序独占进程,且存在 Terminal进度条 等频繁刷新的需要监控的特征信息;
  3. 需要捕获的特征信息存在简体中文,需要做编码转换;

解决方案

如下所示为本例参考代码。使用 Python3 内置模块 subprocess.Popen 建立 channel 。设定参数 encoding='utf8',转码简体中文。设定 universal_newlines=True 以及 bufsize=1 建立缓冲区,以便捕获频繁刷新的进度条等特征信息。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
"""
仅用作demo演示,请勿在真实IPC场景下直接cv代码
sys: Windows
env: Python 3.7.9
"""
import os
import subprocess

title = ""


def _listener():
    global title
    # 如果您还未安装you-get脚手架 请先执行 pip install you-get 或 pip3 install you-get
    # 尝试直接在 Terminal 中运行 `you-get [url]` 查看区别
    # you-get 将嗅探目标链接下的影视资源对象,并保存至当前目录下
    cmd = "you-get https://www.bilibili.com/video/BV1Yv41147QK".split(' ')
    p = subprocess.Popen(
        cmd,
        stdin=subprocess.PIPE,
        stdout=subprocess.PIPE,
        stderr=subprocess.STDOUT,
        universal_newlines=True,
        encoding='utf8',
        bufsize=1
    )
    while subprocess.Popen.poll(p) is None:
        stream = p.stdout.readline()
        print(stream)

        # 仅做演示,首次下载时捕获视频文件名
        if title == "" and stream.startswith("Downloading"):
            title = stream.split(' ')[1]


def demo():
    _listener()
	
	# 仅作演示,自动打开下载好的视频
    try:
        os.startfile(f'{title}')
    except (FileNotFoundError, FileExistsError):
        pass


if __name__ == '__main__':
    demo()

参考资料

[1] subprocess — Subprocess management — Python 3.7.11 documentation

Licensed under CC BY-NC-SA 4.0
You will to enjoy grander sight / By climing to a greater height.