Як менше знати роздільну здатність терміналу?


13

Кожен раз, коли хтось встановлює різний розмір для віртуальної консолі, 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.