如何为终端应用程序编写透明包装器?
How to write a transparent wrapper to terminal application?
Wrapper 应该处理特殊的控制字符并做一些事情但不会干扰实际的应用程序。 (尝试构建类似 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 并未覆盖整个终端 window。它以减少的行数和列数
开始 vim
如果我只是从 shell 中输入 vim 它工作正常:
为什么会发生这种情况以及如何解决?我的目标不仅仅是修复行和列,而且包装器应该是真正透明的,除了捕获特殊的 ctrl 字符并做一些事情。当前 shell 具有的任何 tty / 颜色和其他设置都应该传递给实际的可执行文件。它应该像我输入 vim
一样工作。 (Linux具体的解决方案就好了。不需要全部posix。如果需要c扩展也可以)。
window 大小是 PTY 本身的唯一 属性。您可以使用 TIOCGWINSZ
和 TIOCSWINSZ
ioctls:
获取和设置它
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))
Wrapper 应该处理特殊的控制字符并做一些事情但不会干扰实际的应用程序。 (尝试构建类似 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 并未覆盖整个终端 window。它以减少的行数和列数
如果我只是从 shell 中输入 vim 它工作正常:
为什么会发生这种情况以及如何解决?我的目标不仅仅是修复行和列,而且包装器应该是真正透明的,除了捕获特殊的 ctrl 字符并做一些事情。当前 shell 具有的任何 tty / 颜色和其他设置都应该传递给实际的可执行文件。它应该像我输入 vim
一样工作。 (Linux具体的解决方案就好了。不需要全部posix。如果需要c扩展也可以)。
window 大小是 PTY 本身的唯一 属性。您可以使用 TIOCGWINSZ
和 TIOCSWINSZ
ioctls:
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))