像resize
这样的程序会询问终端的大小。最终,它们会将一些(ANSI)转义序列发送到stdout,并期望终端通过自己返回一些字节来对这些序列做出反应。
该机制的效果通过以下交互式 Python 片段可见:
>>> print('x1b[21;t')
侏儒终端将在 stdin 上明显插入与窗口标题相关的内容。
哪个脚本片段会促使终端写入其大小(以字符为单位)?如果返回大小不可见,则应执行一些简单的转换以查看某些内容。Shell,Python,Perl,任何语言都可以。由于这将是特定于终端的,因此任何常见的终端仿真器都可以(例如xterm,gnome-terminal,terminator等)。
澄清:我不在乎告诉我大小的程序。我知道TIOCGWINSZ,它不能在串行线路上工作。我想看到使用转义序列的代码,它实际上适用于串行行。
以下程序保存当前光标位置;将光标移动到 999,999;向终端查询当前位置;并恢复光标位置。
假设您的终端小于 999x999,这将有效地查询终端的大小。
import sys
print(' 33[s 33[999;999H 33[6n 33[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_IOCTL
和TERMSIZE_USE_CONIO
,CONIO 路由用于 Windows。