每次有人为虚拟控制台设置不同的大小时,less
都会识别窗口分辨率(我假设......);据此,它会改变它应该可视化的文本行数。该参数是如何计算的?
答案1
如果您正在寻找一种从脚本进行检查的方法,您可以执行以下任一操作:
- 按照 manatwork 的建议运行
tput cols
和tput 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
并搜索 TIOCGWINSZ。tput lines
man tty-ioctl
但是,对于其他终端(例如连接到串行端口的终端),无法直接获取此信息。在这种情况下,less
开始在环境变量中寻找线索。
LINES
并且COLUMNS
通常会被设置为终端尺寸。事实上,如果bash
或zsh
可以找到终端尺寸,它会自动设置这些变量本身,以使不太聪明的程序很容易看到终端尺寸。但是,大多数其他 shell(包括dash
和tcsh
)不设置这些变量。TERM
通常设置为终端类型,在这种情况下,terminfo 数据库可能包含终端的预期大小。如果tput rows
无法使用 IOCTL(例如,如果您通过串行端口连接),它将回退到此处记录的值。对于尺寸可以改变的终端,这只是一种猜测,很可能是错误的。
有关更多信息,请参阅man tput
参考资料 控制终端的命令,以及man terminfo
您可以告诉终端执行的操作的列表。
答案2
如果您查看源代码,您就会知道在 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
答案3
我不确定这是否是您正在寻找的信息。我猜想less
注册了一个信号处理程序SIGWINCH
。当终端尺寸发生变化时,它会收到SIGWINCH
信号并探测终端当前尺寸的tty信息。
http://www.gnu.org/software/libc/manual/html_node/Miscellaneous-Signals.html