зміна вікна послідовної консолі?


25

Під час використання послідовної консолі моєї системи я завжди закінчуюсь $COLUMNS=80і $LINES=24.

Хоча я можу змінити ці змінні вручну, це дещо прикро робити це будь-коли, коли змінено вікно терміналу на стороні клієнта.

Зазвичай я підключаюсь до консолі за допомогою screen /dev/mytty baudrate.

Зміна $TERMзмінної середовища на "екран" або "xterm" не допомагає.

Чи потрібно мені зателефонувати gettyз деякими з них замість vt100?

Зайве говорити, що все це працює добре, коли я підключаюсь до тієї ж машини за допомогою ssh.

Відповіді:


26

Як і раніше згадувані мною коментатори, немає альтернативи виклику resizeпісля кожної команди, якщо у вас немає цієї команди і ви не хочете встановлювати пакет там, де він знаходиться ( xterm), ось два сценарії оболонки POSIX, які роблять те саме використовуючи коди аварійних терміналів ANSI:

res() {

  old=$(stty -g)
  stty raw -echo min 0 time 5

  printf '\0337\033[r\033[999;999H\033[6n\0338' > /dev/tty
  IFS='[;R' read -r _ rows cols _ < /dev/tty

  stty "$old"

  # echo "cols:$cols"
  # echo "rows:$rows"
  stty cols "$cols" rows "$rows"
}

res2() {

  old=$(stty -g)
  stty raw -echo min 0 time 5

  printf '\033[18t' > /dev/tty
  IFS=';t' read -r _ rows cols _ < /dev/tty

  stty "$old"

  # echo "cols:$cols"
  # echo "rows:$rows"
  stty cols "$cols" rows "$rows"
}

До речі, у моєму .profileфайлі ви знайдете наступне: [ $(tty) = /dev/ttyS0 ] && res так що розмір терміналу визначається при кожному вході через послідовну лінію (ту, яку я використовую для управління), наприклад після перезавантаження пристрою.
Дивіться також ідею від rsaw в коментарях, щоб [ $(tty) = /dev/ttyS0 ] && trap res2 DEBUGнатомість там був рядок, щоб змінити розмір запускається після кожної команди (зауважте, що AFAIK це не завжди або не завжди можливо для цього busybox).


3
PS: Для того, щоб зробити більш постійним, додайте [[ $(tty) == /dev/ttyS0 ]] && trap res2 DEBUGдо одного з конфігов профілю оболонки (наприклад, /etc/profile, ~/.bash_profile). Це змусить його запускатись після кожної команди (що було б добре, якщо ви змінюєте розмір вікон / панелей за допомогою екрана / tmux / terminal-емулятора).
rsaw

2
Використовуючи його протягом декількох хвилин, я швидко зрозумів, що обидва res& res2занадто повільні для нічого, крім використання при першому вході. На моїх машинах вони обидва беруть 0,5 секунди, щоб закінчити ... і всі мої команди здаються млявими (коли вони використовуються з DEBUG trap). Ого! Не може цього мати. Вгадайте, я буду встановлювати xterm.
rsaw

3
@phk xterm's resizeшвидше частіше - зазвичай 0,002 сек.
rsaw

1
@rsaw О добре, добре знати, я думав, що він буде вести себе подібним чином і тому буде так само повільним. Я пам’ятаю, що той, хто в деяких busyboxес, здавався мені так само повільним.
phk

1
Дякуємо за це автономне рішення. Я використовую дистрибутив, призначений лише для консолі, на якому не встановлено x11 або xterm, тому resizeце не варіант.
thom_nic

16

Тільки для запису, ось відповідь на цю проблему (Usenet переміг):

Консольні додатки , що працюють у віртуальних термінальних додатків ( xterm, rxvtі друзів) буде отримувати SIGWINCHпісля того, як операція зміни розміру має місце. Таким чином, додаток зможе перемалювати вікно тощо у відповідному оброблювачі сигналу.

На жаль, при використанні послідовної консолі такого механізму немає.

Однак програма може активно запитувати поточний розмір вікна консолі. Тож друге найкраще - це робити щоразу, коли командний рядок друкується оболонкою.

Цього можна досягти, спершу скомпілювавши спеціальний виконуваний розмір, а потім скориставшись наступним bashrc:

if [ $(tty) == '/dev/ttyS0' ]; then
  trap resize DEBUG
fi

Звичайно, це не змінить налаштування розміру консолі в консольній програмі під час виконання.


1
Не повинно бути можливим запустити протокол по послідовної лінії, що робить пропонують всі можливості? Я маю на увазі, у нас є клієнт і сервер. Вони можуть використовувати послідовні вхідні програми, щоб зробити майже все, і все ще працювати з простою текстовою послідовною консоллю!
Evi1M4chine

1
Власне, коментар до коду дає зрозуміти, що це не версія, resizeяка встановлена ​​у вашій системі.
Томас Дікі

9

Термінали, що змінюються, є такими результатами NAWS ( Negotiate About Window Sizeвід параметра розміру вікна RFC 1073 Telnet ).

Якщо ви підключені безпосередньо до комп'ютера за допомогою послідовного порту, немає переговорів, і комп'ютер не має прямих знань щодо розміру екрана вашого терміналу.

Якщо термінал може домовитись про розмір, комп'ютер буде надсилати SIGWINCHдодаткам, що працюють в терміналі, кажучи їм оновити своє уявлення про розмір екрану.

Коли комп'ютер не знає розмір екрана, він зазвичай встановлює розмір, показаний stty -a(рядки та стовпці), до нуля. Для інтерактивного використання це трохи недружелюбно, і деякі системи використовують змінні середовища LINESта COLUMNSдопомагають. Призначені значення можуть бути отримані з опису терміналу; частіше вони просто жорсткі. Конвенція для цих змінних вимагає, щоб вони набирали чинності, якщо явно не придушено, наприклад, у use_envфункціях додатків прокляття . З позитивного боку, ці змінні можуть бути корисними, коли немає достовірної інформації. З негативної сторони, немає зручного методу зміни цих змінних.

resizeПрограма (утиліта забезпечена xterm) можна використовувати VT100-стиль звіту позиції курсора послідовність для визначення розміру екрана. Це можна запустити з командного рядка; немає (знову ж таки) немає зручного способу зробити це автоматично. В якості побічного ефекту resizeоновлює інформацію про рядки / стовпці, які бачать stty. Його використання для забезпечення оновлених змінних середовищ в основному корисно для таких випадків, як це, де LINESі COLUMNS буде встановлено, і повинні бути оновлені.


3

Ось ще одне рішення, яке чудово працювало для мене в моїй вбудованій системі Linux (Overo під управлінням Angstrom). Я щойно запустив це з мого файлу .bashrc. Я не хотів використовувати розмір, тому що це вимагає встановлення деяких пакетів X, і я цього не хотів.

Скажіть Raspberry Pi, що ваш термінал більший за 24 рядки | Блог дрібних думок


3
Будь ласка, не публікуйте посилання: включіть відповідну деталь, щоб інформація була доступна і тут ...
jasonwryan

1
Шкода, що йому потрібен Python.
Крейг МакКуїн


1

Під час запуску сеансу оболонки по послідовному рядку достатньо викликати resizeкоманду всередині цього сеансу - після встановлення з'єднання та після зміни геометрії терміналу.

resizeКоманда є частиною XTerm , але не залежить від X11. Наприклад, у Fedora він упакований окремо як xterm-resize.

Як це працює: команда resize вимірює висоту / ширину за допомогою деяких рухів курсору, а потім передає ці значення в термінал за допомогою послідовностей escape.

З оболонкою на зразок zsh це також автоматично оновлює LINESі COLUMNSзмінні (як альтернатива, можна оцінювати операції експорту, які команди друкує до stdout).

Чому це необхідно: за допомогою локального або ssh сеансу термінал може сигналізувати сеанс про зміни геометрії (пор. SIGWINCH). Цей механізм не працює через послідовне з'єднання.


0

Ось проста і швидка функція зміни розміру, яка працює тільки для bash. Він модифікований з resk phk, використовуючи bash, read -d delimщоб уникнути часу очікування закінчення читання.

resize() {
  old=$(stty -g)
  stty -echo
  printf '\033[18t'
  IFS=';' read -d t _ rows cols _
  stty "$old"
  stty cols "$cols" rows "$rows"
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.