Начав изучать тему терминалов в Linux, вы можете почувствовать, что по отдельности вроде бы всё понятно, но разница между понятиями и их суть всё равно ускользает. Консоль, терминал, TTY, виртуальная консоль, виртуальный терминал, эмулятор терминала, оболочка — это просто «вот то чёрное окошко, куда вводят команды Linux». На самом деле за этим окошком скрывается целая цепочка разных сущностей — от компонентов ядра до пользовательских программ. Цель данной статьи — объяснить подсистему TTY и избавить вас от этого неприятного ощущения.

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

Прежде чем погружаться в подсистему TTY, хочу рассказать, как она эволюционировала к тому, чем каждый пользователь, порой даже не задумываясь, пользуется. История берёт начало ещё во времена, когда и компьютеров в привычном понимании не было. А началось всё с телеграфных и тикерных аппаратов.

Телеграфные и тикерные аппараты

Телеграф стал революционным прорывом в развитии информационных технологий, он позволил информации распространяться мгновенно. Но пользоваться им было неудобно. Нужно было уметь пользоваться телеграфным ключом, знать азбуку Морзе, уметь быстро и без ошибок привычный текст кодировать в азбуку Морзе и обратно. Работали аппараты только в одном направлении, т. е. если вам нужно было передать ответ, нужен был второй передатчик и приёмник.

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

Телеграфный аппарат Юза
Телеграфный аппарат Юза
Тикерный аппарат
Тикерный аппарат
Телеграфный аппарат Бодо
Телеграфный аппарат Бодо

Телетайп

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

Teletype Model 33 ASR
Teletype Model 33 ASR

Из-за своей интерактивности телетайп было удобно использовать на ранних компьютерах, таких как PDP-7 или PDP-11 (его подключали в последовательный порт). Но присутствовало расточительное использование бумаги для вывода информации и невысокая скорость печати. Видеотерминалы решали эту проблему.

Видеотерминал

Видеотерминал работал почти как телетайп, но информация выводилась на ЭЛТ-дисплей, что давало ряд преимуществ, например, вы могли выводить информацию не последовательно, а в любой позиции на экране, а если дисплей был цветной, то и в цвете. Меньше было ограничений по выводимым символам, широко распространение получили ESC-коды.

Видео терминал DEC VT100
Видео терминал DEC VT100

Виртуальный терминал

Скриншот виртуального терминала
Скриншот виртуального терминала

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

Псевдотерминал

В появившихся позже псевдотерминалах (PTY) логика эмуляции терминала выносилась из ядра, а в ядре оставалась только базовая логика. На PTY основана работа Telnet, SSH, различные userspace-эмуляторы терминала, Web-терминалы.

Не путайте псевдотерминал (PTY) с эмулятором терминала. PTY — это часть ядра, а эмулятором терминала почти всегда называют пользовательское приложение.

Эмулятор терминала Konsole
Эмулятор терминала Konsole

Итог

В основе видеотерминалов, виртуальных терминалов и PTY лежат архитектура, заложенная ещё во времена телетайпа: ядро является посредником между терминалом и пользовательским приложением. Ядро предоставляет интерфейс для приложения в виде символьного tty-устройства. Приложение читает и пишет в это устройство, в большинстве случаев не зная, какие физические устройства используются для ввода-вывода.

TTY — взгляд сверху

Основная задача подсистемы TTY — обеспечить прозрачный ввод-вывод для пользовательских приложений. С точки зрения процесса в userspace, чем и является пользовательское приложение, TTY — это набор файлов символьных устройств, настраиваемых при помощи системного вызова ioctl(), и в которые можно писать или из которых можно читать при помощи системных вызововwrite() и read().

Стандартные потоки

Когда создаётся процесс в userspace, с которым вы можете работать в терминале, за ним закрепляется несколько файловых дескрипторов (можно сказать идентификаторов открытых файлов): stdin, stdout и stderr. Если процессу необходима информация, он читает её из stdin, если он хочет вывести информацию, то он пишет её в stdout или в stderr, если это какая-то информация об ошибке. В общем случае процессу вообще не важно то, какое физическое устройство ввода или вывода используется, он просто видит файл, используемый для ввода-вывода. Этим файлом является файл символьного tty-устройства.

Оболочка

Возникает вопрос, а как запустить процесс? Ответ: при помощи двух системных вызовов:

  • fork() — для создания копии процесса,

  • execve() — заменяет образ процесса (не вдаваясь в подробности: образ — это файл, содержащий бинарный код программы).

Но кто же делает эти системные вызовы? Например, их делает init-процесс при загрузке операционной системы, когда запускаются процессы для служб. Многие пользователи могут даже не знать об init-процессе и системах инициализации.

В Linux, да и пожалуй в любой Unix подобной системе, есть программы, позволяющие запустить процесс интерактивно, их называют оболочками (shells). Bash, ash, zsh, csh, sh — всё это оболочки. Обычно в системе для конкретного пользователя используется одна из них.

Если вы работали в командной строке Linux, то вы использовали оболочку. Оболочка — это та программа, с помощью которой вы вводите команды Linux. Чтобы в ней работать, нужно запустить эмулятор терминала, такой как GNOME Terminal или Konsole. Но можно воспользоваться и виртуальной консолью (терминалом), доступной по нажатию сочетаний клавиш Ctrl + Alt + F3 .. Ctrl + Alt + F3.

Эмулятор терминала

Эмулятор терминала эмулирует тот самый видеотерминал из 70-х годов прошлого века, приложение взаимодействует через ядро с эмулятором так же, как и в те времена. Для приложения практически нет разницы, оно просто взаимодействует с файлом, за которым закреплены дескрипторы stdin, stdout и stderr. За каждым экземпляром эмулятора терминала (более правильно сказать за каждой сессией) закрепляется свой файл tty. Но TTY — это не просто файл, куда можно писать данные или читать из него.

В зависимости от сценария эмуляция терминала может находиться в разных слоях системы. Для виртуальных консолей она реализована в ядре Linux.
При работе через PTY эмуляция выполняется пользовательским приложением. В случае классического последовательного интерфейса на стороне хоста эмуляции может не быть вовсе — ядро взаимодействует только с драйвером устройства, а подключённым может быть как физический терминал, так и другой компьютер.

Job Control

TTY может управлять процессами. Этот механизм называется Job Control. Я думаю, хоть раз в жизни, но вы нажимали сочетание Ctrl + C, чтобы завершить процесс, тогда вы использовали Job Control. Знать о Job Control полезно, чтобы лучше понять Line Discipline.

Job Control это не только часть функционала Line Discipline. Также это внутренние команды shell и системные вызовы ядра Linux.

Line Discipline

Подсистема TTY устроена так, что информация от терминала не сразу передаётся процессу, а проходит через Line Discipline. Line Discipline — это алгоритмы обработки поступающих от терминала данных перед передачей их процессу, а также перед выводом данных от процесса на терминал.

По умолчанию используется Line Discipline N_TTY. Что она делает? Например, она буферизирует ввод, т. е. процесс не получит данных, пока не придёт код перевода на новую строку 0x0A. Также она выполняет преобразование управляющих кодов в сигналы, которые отсылаются процессам, ассоциированным с данным tty-устройством.

Например, нажатие Ctrl+C эмулятор терминала преобразует в управляющий код 0x03 (ETX), когда этот код обрабатывается Line Discipline на основании настроек, хранимых в termios превращается в сигнал SIGINT, который посылается *Foreground Process Group ассоциированным с tty-устройством, где запущен эмулятор терминала.

Canonical и Raw Mode

Такая обработка не всегда нужна, например, вам будет мешать буферизованный ввод, если вы пишете игру, где нужно реагировать на нажатие клавиш — ваша программа не узнает о нажатых клавишах, пока не будет нажата клавиша ENTER. А если вы разрабатываете текстовый редактор, управляющие коды должны обрабатываться текстовым редактором.

Для этой цели есть специальный режим работы tty-устройства — Raw Mode в противовес Canonical Mode.

Терминал отличается от клавиатуры тем, что контроллер клавиатуры генерирует скан-коды или HID-репорты — низкоуровневые коды, определяющие физическое расположение клавиш, терминал же отправляет коды символов или управляющие коды, которые более высокоуровневые.

Сценарии использования подсистемы TTY

Приведу схемы работы (как движутся потоки данных) для основных сценариев использования подсистемы TTY:

  • подключённый по последовательному порту терминал,

  • использование виртуальных терминалов,

  • использование эмулятора терминала.

Схемы для SSH и Web-терминалов не привожу, будем считать это ваше внеклассное задание.

Подключённый по последовательному порту терминал

Подключённый по последовательному порту терминал
Подключённый по последовательному порту терминал

Использование виртуального терминала

Использование виртуального терминала
Использование виртуального терминала

Использование эмулятора терминала

Использование эмулятора терминала
Использование эмулятора терминала

Консоль и терминал

Многие как и я узнавали о Linux после знакомства с Windows и MS-DOS, и поэтому у вас, скорее всего, неверное есть понимание, что такое консоль и терминал. Попробуйте, не читая дальше, объяснить разницу между консолью и терминалом. Скорее всего после нескольких слов мысли начнут блуждать, и возникнет ощущение — вроде бы всё понятно, но сказать не могу.

Чтобы понять разницу между консолью и терминалом, нужно погрузиться в историю, во времена DEC 11. У этого компьютера среди прочих было два интерфейсная: DL11 — куда обычно подключали телетайп и DH11 — куда можно было подключить до 16 терминальных устройств, в роли которых обычно выступали VT100. Взаимодействие с ядром выполнялось за консолью (DL11), а пользователи работали за терминалами (DH11).

Ядро UNIX выводило сообщения и панику ядра на консоль, также в консоли можно вводить низкоуровневые команды ядру из консоли.

В современном Linux, сообщения ядра выводятся на консоль. Если возникают проблемы при загрузке Linux, пользователю отобразится Recovery Console.

Как ощутить TTY на практике

Теория остаётся абстрактной, пока не закреплена практикой. Поэтому практические примеры в статье приведены в виде команд для выполнения в оболочке. Это позволяет сохранить компактность материала и при этом дать возможность самостоятельно поэкспериментировать.

Посмотреть TTY-устройства в вашей системе

Подсистема TTY представлена в виде символьных устройств в каталоге
/dev.

ls -l /dev/tty*
ls -l /dev/pts

Обратите внимание на:

  • /dev/tty --- управляющий терминал текущего процесса\

  • /dev/tty1 ... /dev/tty7 --- виртуальные консоли\

  • /dev/ptmx --- мастер псевдотерминалов\

  • /dev/pts/N --- slave-части псевдотерминалов\

  • /dev/ttyS0 --- аппаратные последовательные порты\

  • /dev/ttyUSB0 --- USB-UART адаптеры

Важно заметить:

  • тип устройств --- c (character device),

  • major/minor номера,

  • различие между виртуальной консолью и PTY.

TTY --- это драйвер символьного устройства, а не «окно терминала».

Увидеть текущий TTY

tty

Пример вывода:

/dev/pts/3

Также можно посмотреть список процессов:

ps -o pid,tty,cmd

TTY — это атрибут процесса.

Увидеть дескрипторы потоков для процесса

ls -l /proc/$$/fd

Стандартные потоки:

  • 0 - stdin

  • 1 - stdout

  • 2 - stderr

Вывести сообщение на другой терминал

echo "Привет из другого TTY" > /dev/pts/5

TTY — это устройство, в которое можно писать, как в файл.

Запустить команду на другом терминале

Задача по запуску команды на другом терминале более интересная, так как мы должны писать в stdin для процесса, привязанного к этому терминалу. Ранее мы всё равно писали в stdout процесса.
Нам необходимо использовать системный вызов ioctl, чтобы посимвольно сэмулировать работу stdin.

sudo perl -e 'ioctl(STDIN,0x5412,$_) for split //, "ls -la\n"' < /dev/pts/6

0x5412 — это константа TIOCSTI (Terminal I/O Control — STuff Input)

TIOCSTI заставляет ядро Linux вставить указанный символ в очередь ввода того терминала, который привязан к файловому дескриптору stdin в данный момент.

Но здесь stdin перенаправлен через < /dev/pts/6, поэтому символы вставляются не в твой терминал, а в терминал, открытый на /dev/pts/6.

Job Control в действии

sleep 100

Нажатие

  • Ctrl+CSIGINT — завершаем процесс,

  • Ctrl+ZSIGTSTP — приостанавливаем процесс,

jobs
fg

TTY управляет группами процессов.

Посмотреть и изменить настройки termios

stty -a

Отключить эхо:

stty -echo

Чтобы вернуть, нужно вслепую ввести:

stty echo

Что смотреть в исходном коде ядра

Если вы хотите пойти глубже и изучить реализацию на уровне исходного кода, эта глава посвящена разбору конкретных компонентов подсистемы TTY в ядре Linux. Когда вы увидите соответствующие структуры данных и функции, подсистема перестанет восприниматься как «чёрный ящик».

Подход «чёрного ящика» удобен, когда технология используется без необходимости понимать её внутреннее устройство. Однако для системного разработчика знание внутренней архитектуры даёт значительно более глубокое понимание происходящего.

Исходный код ядра довольно динамичен, но подсистема TTY меняется относительно медленно — поэтому 6.12.y вполне репрезентативна.

TTY core — ядро подсистемы

Основные файлы: drivers/tty/tty_io.c, tty_ioctl.c, tty_ldisc.c, tty_buffer.c, tty_port.c

Виртуальные консоли (vc/vt)

Директория: drivers/tty/vt/
Ключевые файлы: vt.c, keyboard.c, vc_screen.c, consolemap.c

Псевдотерминалы (pty / pts)

Основные файлы: pty_master.c, pty_slave.c, ptmx.c (или директория pty/ в некоторых ветках)

Serial / UART

Директория: drivers/tty/serial/
Ключевые файлы: serial_core.c, 8250/8250_core.c (самый распространённый), serial_mctrl_gpio.c и др.

USB serial устройства

Директория: drivers/usb/serial/ + drivers/tty/serial/usb-serial.c
(мост между USB и tty)

Line disciplines (дисциплины линии)

Ключевые файлы: n_tty.c (основная, каноническая дисциплина), tty_ldisc.c (общая логика)

Termios и ioctl-интерфейс

Основные файлы: tty_ioctl.c (TCGETS, TCSETS, TIOCSCTTY и т. д.)

Job control в TTY

Где реализовано: в основном в tty_io.c, tty_ldisc.c, tty.h (tcsetpgrp, foreground process group, SIGTTIN/SIGTTOU)

Полезные ссылки

  1. Linux terminals, tty, pty and shell

  2. Understanding The Linux TTY Subsystem

  3. A Guide to the Terminal, Console, and Shell

  4. Understanding Console, Terminal, TTY, and Shell Demystifying the layers of command-line interfaces

  5. What do PTY and TTY Mean?

  6. How I Went from Confused to Confident: Understanding TTYs, PTYs, SSH, and tmux

  7. Linux console

Выводы

В этой статье мы рассмотрели устройство подсистемы TTY: как пользовательский процесс взаимодействует с терминалом через файловые дескрипторы, какую роль играет Line Discipline, как реализован механизм Job Control и чем отличаются canonical и raw режимы работы.

TTY — это не «магия терминала», а чётко организованный механизм ядра, связывающий процессы, драйверы и сигнальную подсистему.

Разобравшись с этими основами, читать исходный код ядра становится значительно проще: архитектура перестаёт казаться хаотичной, а начинает восприниматься как логичная система.

Тема TTY значительно шире — впереди остаются более глубокое изучение PTY, session management, драйверы конкретных устройств и детали реализации N_TTY.

Понимание этих механизмов — важный шаг к глубокому пониманию архитектуры Linux в целом.

© 2026 ООО «МТ ФИНАНС»