怎么不知道终端分辨率?


Answers:


22

如果您正在寻找一种通过脚本进行检查的方法,则可以执行以下任一操作:

  • 运行tput colstput lines操作说明
  • 检查$ LINES和$ COLUMNS的值

但是,如果您需要详细信息,请继续:

对于虚拟终端(xterm等),有一个ioctl()系统调用将告诉您窗口的大小。如果可以,请less使用此调用。此外,当您更改窗口的大小时,该窗口中正在运行的任何内容都会收到一个SIGWINCH信号,less告知您应该检查新的窗口大小。例如,我开始less运行(作为进程ID 16663),并使用进行连接strace,并调整了窗口的大小。这是我看到的:

$ strace -p 16663
Process 16663 attached - interrupt to quit
read(3, 0xbfb1f10f, 1)                  = ? ERESTARTSYS (To be restarted)
--- SIGWINCH (Window changed) @ 0 (0) ---
rt_sigaction(SIGWINCH, {0x805cf10, [WINCH], SA_RESTART}, {0x805cf10, [WINCH], SA_RESTART}, 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
ioctl(1, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig -icanon -echo ...}) = 0
ioctl(1, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig -icanon -echo ...}) = 0
ioctl(1, TIOCGWINSZ, {ws_row=40, ws_col=80, ws_xpixel=0, ws_ypixel=0}) = 0
ioctl(2, TIOCGWINSZ, {ws_row=40, ws_col=80, ws_xpixel=0, ws_ypixel=0}) = 0

如果可以的话tput cols,这也是tput lines幕后的工作。有关此方法的更多信息,请参见man tty-ioctl并搜索TIOCGWINSZ。

但是,对于其他终端,例如连接到串行端口的终端,则无法直接获取此信息。在那种情况下,less开始寻找环境变量的线索。

  • LINES并且COLUMNS通常会设置为终端尺寸。实际上,如果bashzsh可以找到终端尺寸,它将自动设置这些变量本身,以使不太聪明的程序可以轻松查看终端尺寸。但是,大多数其他shell(包括dashtcsh)都不会设置这些变量。
  • TERM通常设置为终端类型,在这种情况下,terminfo数据库可能包含终端的预期大小。如果tput rows不能使用IOCTL(例如,如果您通过串行端口连接),它将回落到此处记录的值。对于大小可以更改的终端,这只是一个猜测,很可能是错误的。

有关更多信息,请参见man tput有关控制终端的命令,以及man terminfo有关可以告诉终端执行的操作的列表。


terminfo数据库不执行此处指示的操作。@ warl0ck包含的信息较少的答案更加准确。
Thomas Dickey

@ThomasDickey你是对的;它所有的都是期望值。更正了我的答案;谢谢。
詹德

7

如果看一下源代码,您将知道在Linux上检索窗口大小的less调用ioctl()

#ifdef TIOCGWINSZ
    {
        struct winsize w;
        if (ioctl(2, TIOCGWINSZ, &w) == 0)
        {
            if (w.ws_row > 0)
                sys_height = w.ws_row;
            if (w.ws_col > 0)
                sys_width = w.ws_col;
        }
    }
#else
#ifdef WIOCGETD
    {
        struct uwdata w;
        if (ioctl(2, WIOCGETD, &w) == 0)
        {
            if (w.uw_height > 0)
                sys_height = w.uw_height / w.uw_vs;
            if (w.uw_width > 0)
                sys_width = w.uw_width / w.uw_hs;
        }
    }
#endif

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.