Как на самом деле используется команда toe в Linux?

Вот мой взгляд на управляющие последовательности, которые запрашивают эмулятор терминала.

tl;dr :Из-за их асинхронной природы они действительно проблематичны для приложений. (Не с помощью эмуляторов терминала, там это проще простого.)


Во-первых, для простоты предположим, что все эмуляторы терминала гарантированно отправляют ответ на все такие запросы. (Для этого потребуется, чтобы запросы имели четко определенную общую структуру, а не одну -вне escape-последовательностей, что, похоже, не так.)

Давайте спроектируем и реализуем в уме простую утилиту (, такую ​​как «ls» ), а также более сложное полноэкранное приложение (, такое как «mc» или «vim» ), и посмотрим с какими проблемами мы сталкиваемся.

  • Стандартной функцией Unix является то, что вы можете вводить следующую команду, пока выполняется предыдущая (, например. введите «sleep 10» Enter, затем «mc» Enter, затем нажмите F5; примерно через 10 секунд откроется «mc» с диалоговым окном «Копировать» ). Кому-то может нравиться эта функция, а может и не нравиться, но, по крайней мере, поведение должно быть одинаковым для всех приложений, и это поведение приложений, которые не запрашивают динамически эмулятор терминала. Давайте также представим, что «mc» использует такую ​​управляющую последовательность запроса при запуске, чтобы выяснить, какая функция. Теперь mc получит управляющую последовательность F5 перед ответом. Он может игнорировать его (, и в этом случае поведение будет несовместимым с остальными приложениями )или его нужно где-то спрятать, подождать, пока не придет ответ на запрос, а затем обработать эту F5.Чтобы сделать это, он больше не может позволить каждому компоненту читать и обрабатывать непосредственно из стандартного ввода, ему нужен некоторый промежуточный слой-оболочка. Выполнимо, но требует некоторых усилий для реализации (необходимая дополнительная работа заметна даже для проектов, начатых с нуля, не говоря уже о тех, которые уже реализованы без этого критерия и, следовательно, вам приходится сильно рефакторить.)

  • Аналогичная история происходит, если ему необходимо запросить терминал по какой-либо причине во время его работы. Тогда отбрасывание промежуточных «нормальных» символов до прихода ответа абсолютно недопустимо.

  • Теперь вместо утилиты, написанной на C или другом подобном языке, представьте себе сценарий оболочки, которому необходимо прочитать этот ответ, а также другие обычные данные, вводимые пользователем (со стандартного ввода ). Как бы вы пошли? Для каждого «чтения» в вашем коде, обрабатывающем такой ответ, вы бы вручную установили символы завершения в новую строку или конец escape-последовательности ответа, а также нашли и удалили escape-последовательность из остальных? Как сделать так, чтобы ответ escape-последовательности не отображался на экране, пока пользовательский ввод все еще отображается? Как бы вы «подавали» обычный ввод, который вы получаете, ожидая ответа управляющей последовательности, на последующие «обычные» команды «чтения», которые ожидают пользовательские данные? Я не понимаю, как это можно сделать, но даже если и можно, то очевидно, что это невыносимо сложно, утомительно и подвержено -ошибкам. Единственное, что я могу себе представить разумно реализуемым и надежно работающим, - это отбрасывать введенные -символы вперед (, что приводит к необычному поведению ), и обрабатывать такую ​​escape-последовательность ответа только при запуске вашего скрипта.

  • Время обмена данными между эмулятором терминала и приложением может стать значительным, если ваша простая утилита (, например. «ls» )используется в сценарии оболочки внутри цикла. В системах с одним ядром -требуется переключение контекста между двумя приложениями (, утилитой и эмулятором терминала ).хотя, наверное, это не так уж и плохо по сравнению с форком ()+execve ()+friends, который все равно случается. Думаю, в многоядерных -системах в этом нет необходимости, хотя я не уверен в деталях. Однако стоимость (задержки )может стать действительно значительной, если речь идет о реальном сетевом трафике.

  • В редких случаях приложение завершает работу, не прочитав ответ (, например. он падает или уничтожается ), ответ появляется при следующей команде, которую вы начинаете вводить (, что, я уверен, вы уже видели, например. когда вы случайно пометили двоичный файл ).


Теперь давайте предположим, что есть некоторые эмуляторы терминала, которые не распознают (или просто предпочитают не отвечать на )некоторые из запрашиваемых escape-последовательностей, включая будущие. Вот так выглядит текущее положение вещей. Это еще больше усложняет все предыдущие пункты списка. В этом случае вы не можете рисковать зависанием приложения, поэтому ему нужен тайм-аут.

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

  • Что делать, если ответ не приходит вовремя (например. из-за отставания от ssh )? Будет ли ваше приложение продолжать работу в деградированном режиме, видимом пользователю?

  • Что, если ответ придет позже, чем приложение сдастся? Ваше приложение потенциально должно быть готово к такому ответу, приходящему даже в тех местах, где он вообще не ожидал. (. в вашем сценарии оболочки вы сначала запрашиваете некоторое состояние, ждете ответа с тайм-аутом, но каждое отдельное «чтение» позже должно быть подготовлено к тому, чтобы быть загрязненным этим отложенным ответом.)

  • Тайм-аут значительно увеличивает время приема-передачи,вероятно, намного дольше, чем переключение контекста ядра или даже сетевая задержка. Помещать такие команды в цикл сценария оболочки было бы совершенно невыносимо, но, вероятно, даже негативные последствия для удобства использования интерактивных приложений были бы заметны.


В задачу этого ответа не входит демонстрация того, какую альтернативу я считаю осуществимой. Структура переменной TERM также имеет множество ограничений, которые я не буду здесь рассматривать. Для запроса функций (, которые являются статическими для эмулятора терминала, а не текущих свойств, таких как позиция курсора ), я, вероятно, начал бы в направлении TERMCAP, где было описано фактическое поведение. Он может даже указывать на локальный файл и может называться TERM, как и сейчас, но ssh -, как и утилиты, будут нести ответственность за пересылку своего фактического содержимого на удаленный сайт и указывать TERM там на этот файл, аналогично.Xавторитет. Другой совершенно другой подход может состоять в том, чтобы иметь четвертый стандартный файловый дескриптор для такой мета-связи с эмулятором терминала.

2
22.01.2020, 15:42
2 ответа

toeперечисляет описания терминалов, известные Terminfo в системе; по умолчанию он перечисляет только описания, хранящиеся в его каталоге по умолчанию, а не все места, о которых он знает (, например./etc/terminfoв системах на базе Debian -), поэтому

toe

часто ничего не выводит. Чтобы увидеть что-то полезное, запустите

toe -ha

Здесь будут перечислены все записи базы данных Terminfo с заголовком, показывающим, откуда они взяты:

$ toe -ha
#
#/etc/terminfo:
#
#
#/lib/terminfo:
#
hurd            The GNU Hurd console server
wsvt25m         NetBSD wscons in 25 line DEC VT220 mode with Meta
wsvt25          NetBSD wscons in 25 line DEC VT220 mode
linux           linux console

и т. д.

Каждая строка начинается со значения, которое можно использовать с переменной TERM, чтобы программы, совместимые с Terminfo -, использовали соответствующее описание терминала. Вы можете узнать xtermи его варианты в списке...

6
27.01.2020, 21:50

Как упоминалось в toeдокументации (man 1 toe), в нем будут перечислены записи terminfo в

toe(1)                      General Commands Manual                     toe(1)

NAME
       toe - table of (terminfo) entries

SYNOPSIS
       toe [-v[n]] [-ahsuUV] file...

DESCRIPTION
       With no options, toe lists all available terminal types by primary name
       with descriptions.   File  arguments  specify  the  directories  to  be
       scanned;  if  no such arguments are given, your default terminfo direc‐

Например, записи terminfo в моей системе хранятся в/usr/share/terminfo:

$ toe /usr/share/terminfo/ |head -n 10
jaixterm-m  IBM Kanji AIXterm Monochrome Terminal Emulator
jaixterm    IBM Kanji Aixterm Terminal Eemulator
microb      micro bee series
mime        microterm mime1
megatek     pegasus workstation terminal emulator
m2-nam      France Telecom Minitel 2 mode te'le'informatique
mlterm+pcfkeys  fragment for PC-style fkeys
mgterm      MGL/MGL2 MobileGear Graphic Library
ms-vt100    MS telnet imitating dec vt100
mime2a-s    microterm mime2a (emulating an enhanced soroc iq120)

Я ограничил вывод... Теперь, чтобы узнать, что такое terminfo, просто взгляните наman 5 terminfo:

terminfo(5)                      File Formats                      terminfo(5)

NAME
       terminfo - terminal capability data base

SYNOPSIS
       /etc/terminfo/*/*

DESCRIPTION
       Terminfo  is  a data base describing terminals, used by screen-oriented
       programs   such   as   nvi(1),   rogue(1)   and   libraries   such   as
       ncurses(3NCURSES).  Terminfo describes terminals by giving a set of ca‐
       pabilities which they have, by specifying how to perform screen  opera‐
       tions,  and  by  specifying padding requirements and initialization se‐
       quences.  This describes ncurses version 6.1 (patch 20181013).
4
27.01.2020, 21:50

Теги

Похожие вопросы