Как на самом деле работают интерактивные утилиты командной строки? - PullRequest
2 голосов
/ 17 октября 2011

Я понимаю основную концепцию stdin, stdout, stderr и то, как программы работают с командной строкой / терминалом.

Однако мне всегда было интересно, как работают такие утилиты, как less в Linux и git log, потому что они интерактивные.

Моя текущая мысль заключается в том, что программа не завершает свою работу, пишет в стандартный вывод, прослушивает ключевые события и пишет больше в стандартный вывод, пока пользователь не закроет нажатие q или не отправит сигнал закрытия.

Правильна ли моя интуиция или есть что-то еще? Они определяют количество строк и символов в строке, чтобы определить, сколько вывести? И очищают ли они экран всегда перед выводом?

1 Ответ

0 голосов
/ 31 декабря 2012

Очень интересный вопрос, даже если он немного открытый.

Как уже упоминалось @tripleee, ncurses - это базовая библиотека для интерактивных приложений CLI.


Немного истории ...

Терминал == "принтер" ...

Чтобы понять «терминалы» POSIX, вы должны рассмотреть их историю ... более конкретно, вам нужно подумать о том, что означал «терминал» в 70-х годах, когда к последовательному кабелю подключалась клавиатура + принтер. , По мере ввода поток байтов поступает на мэйнфрейм, который возвращает их обратно на принтер, в результате чего принтер выводит команду по мере ее ввода. Затем, обычно после нажатия клавиши ENTER, мэйнфрейм выключается и выполняет некоторую работу, а затем отправляет вывод обратно для печати. Так как это в основном прославленный матричный принтер, мы говорим только о добавлении. Не было никакого «рисования экрана» или чего-то подобного.

Попробуйте это:

echo -e "Hi  there\rBye"

и вы увидите, что он напечатал «Пока». «\ r» - это возврат каретки без перевода строки. каретка - это та часть принтера, которая перемещается назад и вперед в старом матричном принтере и фактически выполняет печать. Поэтому, если вы вернете каретку обратно на левую сторону страницы и не сможете продвинуть бумагу (т. Е. «Перевод строки»), то вы начнете печатать поверх текущей строки текста. "терминал" == "принтер".

Мониторы и программные терминалы ... по-прежнему ориентированы на линию

Итак, немного вперед, и появилась революционная технология под названием «мониторы», где у вас есть виртуализированный дисплей терминала, который можно переписать. Как и все хорошие технологии, мы постепенно вводили новшества, добавляя все новые и новые специальные коды. Например, проверьте цветовые коды ANSI . Если вы находитесь на терминале, который не распознает эти escape-коды, вы увидите кучу тарабарщины в выводе этих неинтерпретированных кодов:

    "methodName": ESC[32m"newInstance"ESC[39m,
    "fileName": ESC[32m"NativeConstructorAccessorImpl.java"ESC[39m,
    "className": ESC[32m"sun.reflect.NativeConstructorAccessorImpl"ESC[39m,
    "nativeMethod": ESC[33mfalseESC[39m,

Когда ваш терминал видит '\ 033' (ESC), '[', ..., 'm', он интерпретирует его как команду для изменения цвета. Попробуйте это:

 echo  -e "\033[32mgreen\033[39m"

Так или иначе, это история / наследие терминальной системы Unix, которая затем была унаследована Linux и BSD (например, macs) и полу-стандартизирована как POSIX . Посмотрите termio.h , который определяет интерфейс ядра для взаимодействия с терминалами. Почти наверняка в Linux / BSD есть множество более продвинутых функций, которые не полностью стандартизированы в POSIX. Говоря о «стандартах», существует также множество стандартов протоколов терминальных устройств, таких как почтенный VT100 . Программные «эмуляторы терминалов», такие как SSH или PuTTY, знают, как говорить на VT100, и, как правило, на более сложных диалектах.

Интерактивное взаимодействие с обувью на линейном интерфейсе ...

Так что ... интерактивное ... это не совсем подходит для линейного принтера. Это наслоено сверху. Ввод прост; вместо того, чтобы автоматически выводить каждое нажатие клавиши и ждать ввода ENTER (ala "readline" ), у нас есть программа, потребляющая нажатия клавиш, когда они поступают из TTY. Вывод более сложный. Несмотря на то, что фундаментальная абстракция представляет собой поток выходных данных, с достаточным количеством escape-кодов вы можете перекрасить экран, поместив "каретку" и написав новый текст поверх старого текста (точно так же, как с моим "\ r" примером). Ничто из этого не является забавным для реализации самостоятельно, особенно если вы хотите поддерживать несколько сред с разными управляющими кодами. .... таким образом библиотеки, из которых ncurses является одним из самых известных. Чтобы понять причудливую магию, сделанную для эффективного рендеринга динамического экрана в линейно-ориентированный TTY, посмотрите Вывод и обновление экрана из "Руководства хакера по NCURSES".

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...