【问题标题】:subprocess that prints to pseudo terminal is not using full terminal size打印到伪终端的子进程未使用完整的终端大小
【发布时间】:2022-01-06 22:24:26
【问题描述】:

我有以下程序将top 包装在伪终端中并将其打印回真实终端。

import os
import pty
import subprocess
import sys
import time

import select

stdout_master_fd, stdout_slave_fd = pty.openpty()
stderr_master_fd, stderr_slave_fd = pty.openpty()

p = subprocess.Popen(
    "top",
    shell=True,
    stdout=stdout_slave_fd,
    stderr=stderr_slave_fd,
    close_fds=True
)

stdout_parts = []
while p.poll() is None:
    rlist, _, _ = select.select([stdout_master_fd, stderr_master_fd], [], [])
    for f in rlist:
        output = os.read(f, 1000)  # This is used because it doesn't block
        sys.stdout.write(output.decode("utf-8"))
        sys.stdout.flush()
    time.sleep(0.01)

这很好,控制序列按预期处理。但是,子进程并未使用真实终端的完整维度。

为了比较,运行上面的程序:

直接运行top

我没有找到 pty 库的任何 api 来建议可以提供尺寸。

我在实践中为伪终端获得的尺寸是 24 行的高度和 80 列的宽度,我假设它可能在某处被硬编码。

【问题讨论】:

标签: python terminal subprocess pty


【解决方案1】:

阅读Emulate a number of columns for a program in the terminal,我发现了以下可行的解决方案,至少在我的环境中(OSXxterm

echo LINES=$LINES COLUMNS=$COLUMNS TERM=$TERM

在我的 shell 中是 LINES=40 COLUMNS=203 TERM=xterm-256color。然后在脚本中设置以下内容会得到预期的输出:

p = subprocess.Popen(
    "top",
    shell=True,
    stdout=stdout_slave_fd,
    stderr=stderr_slave_fd,
    close_fds=True,
    env={
        "LINES": "40",
        "COLUMNS": "203",
        "TERM": "xterm-256color"
    }
)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-04-12
    • 2020-09-18
    • 2022-11-02
    • 2013-06-27
    • 2013-09-14
    • 1970-01-01
    • 1970-01-01
    • 2020-02-24
    相关资源
    最近更新 更多