如何为终端应用程序编写透明包装?

时间:2019-03-26 17:45:58

标签: python linux console tty pty

包装程序应处理特殊的控制字符并执行某些操作,但不干扰实际的应用程序。 (尝试构建类似tmux的应用)

到目前为止,我在文档中有以下修改示例:https://docs.python.org/3/library/pty.html#example

import pty
import os

def handle_special_cmd(data):
    # TODO
    raise NotImplementedError

def inread(fd):
    data = os.read(fd, 1024)
    if b'\x02' in data: # ctrl B
        return handle_special_cmd(data)
    return data

def main():
    cmd="vim"
    pty.spawn(cmd, stdin_read=inread)

if __name__=='__main__':
    main()

上面的代码有效,但是打开的vim不能覆盖整个终端窗口。它以减少行和列bad vim

的vim开始

如果我只是从shell键入vim,它将正常工作: good vim

为什么会发生这种情况以及如何解决?我的目标不仅是修复行和列,而且包装程序应该真正透明,除了捕获特殊的ctrl字符并做一些事情。当前外壳程序所具有的tty / colors和其他设置,都应该传递给实际的可执行文件。它应该像我键入vim一样工作。 (Linux特定的解决方案很好。不需要在所有posix中都可以工作。如果需要c扩展名也可以)。

1 个答案:

答案 0 :(得分:1)

唯一地,窗口大小是PTY本身的属性。您可以使用TIOCGWINSZTIOCSWINSZ ioctl进行设置:

import sys, fcntl, termios, struct

buf = bytearray(4)
fcntl.ioctl(sys.stdin.fileno(), termios.TIOCGWINSZ, buf)
(h, w) = struct.unpack("HH", buf)
print("Terminal is {w} x {h}".format(w=w, h=h))

[...]

fcntl.ioctl(child_pty.fileno(), termios.TIOCSWINSZ, struct.pack("HH", h, w))