# Терминалы
## Hello, World! Глубокое погружение в Терминалы
![terminal](1.jpeg)

- **Terminal**

Terminal (терминал) — это комбинация дисплея и клавиатуры, то есть физическое устройство.
До того, как терминалы стали именно данной комбинацией, они являлись неким устройством под названием teleprinter (teletype, teletypewriter или TTY сокращенно), то есть комбинацией принтера и клавиатуры. 
Обычно несколько терминалов подключались к одному и тому же компьютеру. 
Таким образом возможно было работать нескольким пользователям за одним и тем же компьютером, причем каждому выделялась своя сессия, независимая от других. 
Терминал был назван так потому, что он находился на конце терминального кабеля (terminal end).

Это Teletype:
![Teletype](2.jpeg)

А это Terminal:
![Teletype](3.jpeg)

- **Console**

Console (консоль) — терминал, который подключен напрямую к компьютеру. 
Дело в том, что большинство терминалов были соединены неявно, но хотя бы один был подключен напрямую к компьютеру. 
Консоль было разрешено использовать строго определенному кругу лиц, так как она позволяла настраивать компьютер.

- **Shell**

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

Shell — это command line interpreter. 
Главное предназначение — запускать другие программы. 
Существует большое количество различных Shell'ов. 
Самым распространенным является Bash (от англ. Bourne Again SHell, что как подсказывает Википедия, является каламбуром для «Born again» Shell, то есть «возрождённый» Shell). 
Другие примеры: Dash (легковесный Shell, доступен, если запустить бинарник по адресу /bin/sh), Zsh.

Конечно же, и терминалы, и консоли не могли не найти своего отражения в современности. 
Поэтому далее мы рассмотрим такие вещи, как Terminal Emulator и Virtual Console.

- **Terminal Emulator**

Terminal Emulator — эмулятор старого доброго терминала. Эмулятор терминала требуется для программ, которые не могут напрямую взаимодействовать с X Window System — Bash, Vim и прочие.

Давайте для начала установим обязанности терминала:

    - Передача ввода пользователя в компьютер
    - Доставка вывода компьютера на дисплей

Так и наш Terminal Emulator выполняет абсолютно то же самое: он доставляет ввод пользователя в запущенную программу, а также отображает вывод программы на дисплей. 
В любом случае, смысл сохраняется — между пользователем и запущенной программой, существует какой-то слой, отвечающий за ввод/вывод. 
Примеры Terminal Emulator: gnome-terminal, xterm, konsole.

Прошу не путать Shell и Terminal Emulator!
Terminal Emulator — GUI приложение, то есть окно в X Window System. 
Shell — это command line interpreter, то есть просто исполнитель команд, он не имеет графической оболочки. 
Если говорить совсем правильно, вы не запускаете Bash, вы запускаете Terminal Emulator, который запускает внутри себя Bash. 
Terminal Emulator и Bash — абсолютно 2 различные программы. 
Первая отвечает исключительно за ввод/вывод, вторая — за обработку команд.

Далее в докладе все упоминания терминала будут относиться к эмулятору терминала.

- **Virtual Console (Virtual Terminal)**

Нажмите Ctrl+Alt+FN, где N, обычно, имеет значения от 1 до 6. 
То, что вы сейчас видели — называется Virtual Console (виртуальная консоль) или Virtual Terminal (виртуальный терминал). 
Множество терминалов были подсоединены к одному компьютеру и каждый терминал был отдельной сессией, независимой от других. 
Virtual Console повторяет эту идею: внутри вашего компьютера может быть несколько независимых сессий (однако, ресурсы компьютера все же, очевидно, общие).

Вы можете именовать данную сущность как Virtual Console, так и Virtual Terminal, так как по определению, консоль — это терминал, подключенный напрямую к компьютеру, 
но ведь все виртуальные терминалы в каком-то смысле подключены напрямую к компьютеру.

- **TTY устройства**

Каждому терминалу назначается свое TTY устройство (терминальное устройство), которое обеспечивает работу консоли. 
Хотя телетайпы вы вряд ли уже найдете, но сокращение TTY дошло и до наших дней.

TTY устройство состоит из двух фундаментальных компонентов:

    - Драйвер устройства. Он отвечает за доставку ввода с клавиатуры в программу и за отображение вывода программы на экран.
    - TTY Line Discipline (рус. — дисциплина линии). Дисциплина линии — это интерфейс доступа к драйверу, который, однако, привносит немало логики в TTY устройство. Можно сказать, что дисциплина линии проксирует вызовы к драйверу.

Строение TTY устройства:

![terminal](4.jpeg)

Существует 3 типа TTY устройств:

    - Console device — обеспечивает работу Virtual Console. Ввод и вывод данного устройства управляется полностью ядром.
    - PTY device (псевдотерминал) — обеспечивают работу терминала в оконном интерфейсе. Ввод и вывод данного устройства управляется эмулятором терминала, который работает в пользовательском пространстве.
    - Serial device — общается напрямую с железом. Обычно не используется напрямую, а существует как самый нижний уровень в организации архитектуры терминального устройства.

- **Terminal Emulator и Pseudoterminal**

Каждый раз, когда мы открываем новый терминал в X Window System, GNOME Terminal Server порождает новый процесс и запускает в нём выбранную по умолчанию программу. Обычно, это какой-то Shell (например, Bash).

Общение с запущенной программой происходит через так называемый Pseudoterminal (псевдотерминал, PTY). Сам псевдотерминал существует в ядре, однако ввод получает из пользовательского пространства — из эмулятора терминала.

Псевдотерминал состоит из следующих двух виртуальных TTY устройств:
1) PTY master (PTM) — ведущая часть псевдотерминала. Используется GNOME Terminal Server для передачи ввода с клавиатуры в запущенную внутри терминала программу, а также для чтения вывода программы и отображения вывода на дисплей. GNOME Terminal Server в свою очередь общается с X Window System по X протоколу.
2) PTY slave (PTS) — ведомая часть псевдотерминала. Используется программой, запущенной внутри терминала, для чтения ввода с клавиатуры и отображения вывода на экран. По крайней мере, так думает сама программа (объясню, что это значит, чуть далее).

Любые данные, записанные в PTS устройство, являются вводом PTM устройства, то есть становятся доступны для чтения на PTM устройстве. И наоборот: любые данные, записанные в PTM устройство, являются вводом PTS устройства. Именно таким образом и происходит общение GNOME Terminal Server и запущенной внутри терминала программы. Каждому PTM устройству сопоставляется свое PTS устройство.

Процесс запуска нового терминала выглядит примерно следующим образом:
1) GNOME Terminal Server создает master и slave устройства с помощью вызова функции open() на специальном устройстве /dev/ptmx. Вызов open() возвращает файловый дескриптор созданного PTM устройства — master_fd.
2) GNOME Terminal Server создает новый процесс с помощью вызова функции fork(). Данный процесс и будет являться новым терминалом.
3) В терминале PTS устройство открывается на файловых дескрипторах 0, 1, 2 (stdin, stdout и stderr соответственно). Теперь стандартные потоки ввода/вывода терминала ведут на данное устройство.
4) В терминале запускается нужная программа с помощью вызова функции exec(). Обычно запускается какой-то Shell (например, Bash). Любая программа, запущенная впоследствии из Bash, будет иметь те же файловые дескрипторы, что и сам Bash, то есть потоки программы будут направлены на PTS устройство.

![terminal](5.jpeg)

-**Заключение**

Подведем итог. В данной статье мы узнали:

    - Как работают эмуляторы терминалов
    - Что такое виртуальные устройства
    - Что такое TTY устройства
    - Как устроены псевдотерминалы

### Список литературы

[https://habr.com/ru/post/460257/](habr)