Я подключаюсь к удаленным серверам Linux с помощью SSH через эмулятор терминала PuTTY. Я замечаю, что команды, которые я запускаю, и вывод на консоли продолжают добавляться в окно терминала. Я имею в виду, что когда я использую полосу прокрутки и прокручиваю вверх/вниз, я могу видеть предыдущие команды, которые я запускал, и их вывод, как на распечатанной бумаге. Однако некоторые команды, например, top
постоянно обновляют вывод, не отображаясь как добавление на консоли. Как это работает?
решение1
Потенциально здесь действуют два механизма.
Один из них — использование управляющих кодов ANSI (и других не-ANSI кодов в некоторых случаях), как упомянул Мартин Прикрил в своем ответе, для реализации текстового псевдографического интерфейса. Минимально для этого — ровно два определенных управляющих кода ANSI, , ^[[2J
который стирает все на экране, и ^[[;H
, который перемещает курсор в верхний левый угол экрана. Объединив их, вы можете выписывать содержимое каждого «кадра» по одному, не добавляя его в буфер прокрутки. Большинство приложений на самом деле используют гораздо больше, чем просто эти (например, есть набор кодов для перемещения курсора в произвольных направлениях, и вполне нормально использовать их для пропуска частей экрана, которые должны быть «пустыми»). На практике большинство (но далеко не все) крупных приложений используют либо libcurses (или, что чаще, ncurses), либо прямой эквивалент для обработки всего этого за них.
Другая возможность, которая обычно сочетается с использованием escape-кодов ANSI для управления содержимым экрана, — это специальная функция, изначально предоставленная xterm, но теперь широко реализованная большинством приличных эмуляторов терминала, называемая альтернативным буфером экрана. Существует пара escape-кодов ( ^[[?1049h
и ^[[1049l
), используемых для переключения между этим и обычным буфером прокрутки. Переключившись на альтернативный буфер экрана перед представлением текстового пользовательского интерфейса, программы могут полностью избежать изменения буфера прокрутки, что не только не позволяет вам прокручивать без необходимости перехватывать нажатия клавиш, которые обычно прокручивают, но и позволяет программе делать такие вещи, как позволять вам проверять существующее содержимое терминала до запуска программы (и облегчает просмотр того, что вы делали до открытия этого полноэкранного приложения).
решение2
То, что вы наблюдаете, является продуктом исторического развития.
Первые интерактивные терминалы были верны богутелетайпы; по сути, электрические пишущие машинки, подключенные к телефонной линии. (Вы когда-нибудь задумывались, почему /dev/телетайп(назван так, как назван?) Вы можете ввести текстовую команду (с, iirc, даже с некоторыми базовыми, неуклюжими правками строк) и получить текстовый вывод.
Они, конечно, могли двигаться только слева направо и сверху вниз. Ой, подождите, это неправда! Они могли вернуться на один символ назад с помощью Ctrl-H и набрать его снова, сделав его жирным. Вот, вот чтонекоторые программы все еще делаюткоторые форматируют текст для принтеров. Телетайпы также имели несколько основных кодов управления, таких как перевод строки, перевод страницы или звонок.
Шаг к терминалу на основе ЭЛТ был логичен, хотя бы для того, чтобы спасти деревья. Но с тех пор каждый терминал (эмулятор) обеспечивает базовую функцию телетайпа: если не указано иное (со знаменитыми escape-последовательностями), полученные 7-битные коды ASCII, включая базовые коды управления, интерпретируются как соответствующие символы или команды и отображаются слева направо, сверху вниз, начиная с текущей позиции курсора, которая поддерживалась терминалом.
Но поскольку более умные терминалы фактически могли отображать символы в произвольных позициях строк/столбцов на экране, у всех них были некоторые средства делать это программно, через последовательности управляющего кода, и операционные системы были так или иначе настроены на использование соответствующих последовательностей. Некоторые программы, в частности редакторы, оболочки и другие интерактивные, ориентированные на пользователя программы, такие как top, используют эту возможность для управления всем экраном.
Причина, по которой этот «визуальный режим» не так распространен, заключается в том, что простой вывод линейной последовательности символов без «украшения» чрезвычайно универсален — и в то же время достаточен для широкого спектра выходных данных: вы можете распечатать табличные данные, которые по сути являются последовательной последовательностью символов с пробелами (пробел, табуляция, новая строка). Вся экосистема Unix/Linux с каналами и устройствами построена вокруг этой парадигмы. Она позволяет вам соединять «строительные кирпичики», такие как find, grep, cut и т. д., вместе и автоматически обрабатывать текстовую информацию. Это было бы совершенно невозможно, если бы вывод смешивался с командами позиционирования и форматирования.
решение3
Большинство команд просто печатают строки на терминале. Клиент терминала просто печатает эти строки так, как это делали древние линейные принтеры. Прокрутка — это представлениебесконечная бумагавыходит из принтера.
Но терминальный клиент (он жеэмуляторы терминала) может делать гораздо больше, включая такие вещи, как перемещение курсора по экрану и, таким образом, позволяя серверу (удалённому приложению) печатать в произвольной точке "терминального экрана". Это то, что приложения, такие как top
, vi
, Midnight Commander и т. д., делают из нас, чтобы реализовать полноэкранный "GUI" интерфейс (на самом делеTUI-интерфейс). Эти расширенные функции реализованы с использованиемEscape-коды ANSI.