Каждый раз, когда кто-то устанавливает другой размер для виртуальной консоли, less
распознает разрешение окна (я предполагаю, что ...); в соответствии с этим он меняет, сколько строк текста он должен визуализировать. Как вычисляется этот параметр?
решение1
Если вы ищете способ проверки из скрипта, вы можете сделать одно из следующих:
- Запустите
tput cols
иtput lines
, как предлагает manatwork - проверьте значения $LINES и $COLUMNS
Но если вам нужны подробности, вот они:
Для виртуальных терминалов (xterm и т. д.) есть ioctl()
системный вызов, который сообщит вам размер окна. Если он может, less
он использует этот вызов. Кроме того, когда вы меняете размер окна, все, что выполняется в этом окне, получает сигнал SIGWINCH
, который сообщает less
, что ему следует проверить новый размер окна. Например, я запустил less
выполнение (как процесс с идентификатором 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
часто будет установлен на размеры терминала. Фактически, еслиbash
илиzsh
может найти размеры терминала, он автоматически установит эти переменные сам, чтобы не очень умным программам было легче увидеть размер терминала. Однако большинство других оболочек, включаяdash
иtcsh
, не устанавливают эти переменные.TERM
обычно устанавливается на тип терминала, в этом случае база данных terminfo может содержать ожидаемый размер терминала. Еслиtput rows
не удается использовать IOCTL (например, если вы подключены через последовательный порт), он вернется к значениям, записанным здесь. Для терминала, размер которого может меняться, это всего лишь предположение, и оно, скорее всего, будет неверным.
Более подробную информацию см. man tput
в разделе о командах для управления терминалом и man terminfo
о списке действий, которые можно выполнить с помощью терминала.
решение2
Если вы посмотрите исходный код, то вы узнаете less
вызовы ioctl()
для получения размера окна в Linux.
#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