Как меньше узнает разрешение терминала?


12

Каждый раз, когда кто-то устанавливает другой размер для виртуальной консоли, lessраспознает разрешение окна (я предполагаю, что ...); в соответствии с этим, он меняет количество строк текста, которое он должен визуализировать. Как рассчитывается этот параметр?


Хм ... хорошо, но где я могу найти ту процедуру, которая выполняется?
Джузеппе Крино

Ответы:


22

Если вы ищете способ проверки из скрипта, вы можете сделать одно из следующих:

  • Беги tput colsи tput lines, как подсказывает Манатворк
  • проверьте значения $ 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список вещей, которые вы можете указать терминалу делать.


База данных terminfo не делает того, что было указано здесь. Ответ @ warl0ck, который содержит меньше информации, является более точным.
Томас Дики

@ThomasDickey Ты прав; все это имеет ожидаемые значения. Исправил мой ответ; Благодарю.
Декабрь

7

Если вы посмотрите на исходный код, вам будут известны 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

1

Я не уверен, что это та информация, которую вы ищете. Я думаю, lessрегистрирует обработчик сигнала для SIGWINCH. Когда измерение терминала изменяется, он получает SIGWINCHсигнал и проверяет tty информацию для текущего измерения терминала. http://www.gnu.org/software/libc/manual/html_node/Miscellaneous-Signals.html

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.