如何"手动"让我的终端返回其(字符)大小?



resize这样的程序会询问终端的大小。最终,它们会将一些(ANSI)转义序列发送到stdout,并期望终端通过自己返回一些字节来对这些序列做出反应。

该机制的效果通过以下交互式 Python 片段可见:

>>> print('x1b[21;t')

侏儒终端将在 stdin 上明显插入与窗口标题相关的内容。

哪个脚本片段会促使终端写入其大小(以字符为单位)?如果返回大小不可见,则应执行一些简单的转换以查看某些内容。Shell,Python,Perl,任何语言都可以。由于这将是特定于终端的,因此任何常见的终端仿真器都可以(例如xterm,gnome-terminal,terminator等)。

澄清:我不在乎告诉我大小的程序。我知道TIOCGWINSZ,它不能在串行线路上工作。我想看到使用转义序列的代码,它实际上适用于串行行。

以下程序保存当前光标位置;将光标移动到 999,999;向终端查询当前位置;并恢复光标位置。

假设您的终端小于 999x999,这将有效地查询终端的大小。

import sys
print('33[s33[999;999H33[6n33[u')
print(repr(next(sys.stdin)))

资源:

  • https://en.wikipedia.org/wiki/ANSI_escape_code
  • VT100 ANSI 转义序列:获取屏幕大小、条件 ANSI

我在 http://code.metager.de/source/xref/gnu/coreutils/src/stty.c#1739 从GNU的stty(1)源中提升了这项技术。 我在OS X上测试了它,我不能保证它可以在其他地方工作,但它值得一试。

import fcntl
import termios
import struct
pad = "0" * 8
s = fcntl.ioctl(1, termios.TIOCGWINSZ, pad)
sz = struct.unpack('hhhh', s)
print("rows: {} columns: {}, xpixels: {}, ypixels: {}". format(*sz))

在我的机器上给出:

rows: 24 columns: 80, xpixels: 1200, ypixels: 600

编辑:os.get_terminal_size的源代码与一个名为get_terminal_size的函数Modules/posixmodule.c。 其中一种机制是如上所示的,但还有其他机制取决于宏TERMSIZE_USE_IOCTLTERMSIZE_USE_CONIO,CONIO 路由用于 Windows。

最新更新