Вместе изучаем Linux. Введение. Терминал и полезные команды
Здравствуйте! Я Анатолий Гусляков, модератор сайта Comss.ru. С сегодняшнего дня мы открываем серию интересных тем под общим названием «Вместе изучаем Linux». Темы обсуждений будут в виде статей или сообщений, в которых будут рассматриваться различные материалы по изучению Ubuntu и его производных систем. Материал будет выкладываться не только администрацией ресурса, но и пользователями, желающими поделится своими знаниями (интересны именно личные знания, без копипаста со сторонних ресурсов). Если будут выкладываться объемные темы, предварительно необходимо обговорить с администрацией ресурса, возможно предложенная тема будет выложена в виде отдельной статьи.
Цель — изучение азов Linux систем. Методика, наверное, не совсем обычная, учителей не будет, вернее, каждый пользователь принимающий участие, и будет являться учителем. Открыто в добродушной и теплой обстановке мы будем делиться своими знаниями. Каждая тема обсуждения (урока) будет заканчиваться практическим закреплением новых знаний на своей системе и комментариями со скриншотами.
Начнем первое обсуждение!
Терминал и полезные команды
Еще на этапе предварительного изучения Linux системы (этап: что такое Linux и с какой стороны к нему подойти), пользователь встречает такой термин как Терминал. Кого-то он отпугивает, а у кого-то наоборот появляется желание попробовать (а почему бы не попробовать себя в роли программиста? 🙂 ) . Там же в сети мы находим информацию среди комментариев пользователей, что оказывается с помощью этой штуки управляют всей системой, устанавливают программы, исправляют ошибки и вообще все с его помощью делают.
Терминал — графическая программа эмулирующая консоль, говорит нам пользовательская документация с сайта help.ubuntu.ru.
Все команды терминала работают и в консоли. Консоль работает без графической оболочки и как правило необходима при проблемах с запуском системы.
Так что же такое Терминал? Терминал — это инструмент который позволяет управлять системой напрямую, а так же позволяет увидеть любое наше действие, производимое в любой графической программе и в целом в системе, т.е и открытие пользователем любой папки и открытие любой программы, в тот же самый момент происходят в виде команд в терминале.
Примеры наиболее популярных команд (терминал можно запустить с помощью горячих клавиш: Ctrl+Alt+T):
sudo apt-get update (обновление индекса пакетов)
sudo apt-get upgrade (непосредственное обновление программ)
Рассмотрим составляющие команды:
- sudo — команда запуска с правами администратора (после ее ввода необходимо ввести пароль администратора, сам пароль не виден, но пугаться не стоит, он вводится и затем жмем клавишу enter);
- apt-get — является мощным инструментом по установке и обновлению пакетов;
- update — обновление списка пакетов, upgrade — обновление самих пакетов.
sudo apt-get install название_программы — установка программы;
sudo apt-get remove название_программы — удаление программы;
Программы лучше всего устанавливать, добавляя их репозитории, это даст возможность дальнейшего автоматического обновления программы, предварительно проверив что программы нет в Центре приложений Ubuntu (таким образом проверяем если данный репозиторий у нас не подключен).
Для большинства команд можно получить справку, введя после команды дополнительную команду —help. Пример: sudo apt-get update —help
Рекомендую ознакомиться и добавить в закладки ссылку: Очень полезные команды Linux на одном листе.
Предлагаю каждому пользователю поделиться скриншотом запущенной полезной команды.
И напоследок несколько интересных команд:
uname -a — команда выводит на экран версию ядра Linux;
netstat -tup — список активных сетевых соединений;
apt-get moo — команда хорошего настроения
Популярные эмуляторы терминала
Как оказывается есть различные эмуляторы терминала. Каждый их них по-своему интересен.
Рассмотрим наиболее популярные эмуляторы терминала:
Guake — ниспадающий терминал, напоминающий консоль из популярной игры Quake. Терминал загружается в память, поэтому вызов терминала происходит быстрее стандартного терминала. Доступен в репозитории Ubuntu, поэтому установить можно из Центра приложений Ubuntu.
Final term — «умный» эмулятор терминала. Запоминает вводимые команды и при следующем наборе предлагает их в выпадающем меню. Как и большинство эмуляторов терминала, Final term поддерживает работу горячих клавиш, но через редактирование файла настроек. К сожалению, при ознакомлении он завис, но на это есть объяснение, Final term длительное время не выходит из этапа альфа тестирования.
Переходим к установке. На момент написания данной статьи репозиторий программы не работал, поэтому устанавливать будем из исходников. Дополнительный инструмент Git, который установим для установки Final term нам пригодится в дальнейшем для установки других программ.
sudo apt-get install git build-essential cmake intltool (необходимые довольно популярные инструменты)
sudo apt-get install valac libgtk-3-dev intltool clutter-gtk-1.0 libkeybinder-3.0-dev libgee-0.8-dev libnotify-bin libmx-dev (дополнительные пакеты для GTK )
git clone https://github.com/p-e-w/finalterm.git (загружаем исходники)
cd finalterm/ (переходим в папку finalterm)
mkdir build (создаем папку build )
cmake .. (инструмент для автоматической сборки программы из исходного кода)
make (инструмент для автоматической сборки программы из исходного кода)
sudo make install (непосредственно установка)
Terminator — кроссплатформенный эмулятор терминала, поддерживающий системы Microsoft Windows, Mac OS X, Linux , Unix X11. Удобный эмулятор терминала, позволяет создать горизонтальные и вертикальные вкладки, настроить отображение интерфейса, множество горячих клавиш и подключить дополнительные плагины.
Установить можно из Центра приложений Ubuntu.
RXVT (цветной терминал с поддержкой unicode) — очень легковесный эмулятор терминала. Никаких настроек не обнаружил. По минимализму напоминает встроенный XTerm, однако в RXVT удалены некоторые функции, такие как: эмуляция Tektronix 4014 и конфигурирование в инструментальном стиле.
Доступен в родном репозитории Ubuntu.
Ну а тем, кто продолжает использовать стандартный Терминал предлагаю его немного украсить рисунком, например пингвином по имени Tux (официальный талисман Linux).
sudo apt-get install cowsay fortunes-ru
Далее открываем домашнюю папку (папка Home/имя пользователя), включаем отображение скрытых файлов и редактируем файл с названием .bashrc, добавляя в него строчку: fortune | cowsay -f tux
An Introduction to the Linux Terminal
This tutorial, which is the first in a series that teaches Linux fundamentals, covers getting started with the terminal, the Linux command line, and executing commands. If you are new to Linux, you will want to familiarize yourself with the terminal, as it is the standard way to interact with a Linux server.
If you would like to get the most out of this tutorial, you will need a Linux server to connect to and use. If you do not already have one, you can quickly spin one up by following this link: How To Create A DigitalOcean Droplet. This tutorial is written for an Ubuntu 22.04 server but the general principles apply to any other distribution of Linux.
Let’s get started by going over what a terminal emulator is.
Terminal Emulator
A terminal emulator is a program that allows the use of the terminal in a graphical environment. As most people use an OS with a graphical user interface (GUI) for their day-to-day computer needs, the use of a terminal emulator is a necessity for most Linux server users.
Here are some free, commonly-used terminal emulators by operating system:
- Mac OS X: Terminal (default), iTerm 2
- Windows: ConEmu, Windows Terminal, PuTTy
- Linux: Gnome Terminal, Konsole, XTerm
Each terminal emulator has its own set of features. In general, you should expect a modern terminal emulator to support tabbed windows and text highlighting.
The Shell
In a Linux system, the shell is a command-line interface that interprets a user’s commands and script files, and tells the server’s operating system what to do with them. There are several shells that are widely used, such as the Bourne-Again shell ( bash ) and Z shell ( zsh ). Each shell has its own feature set and intricacies regarding how commands are interpreted, but they all feature input and output redirection, variables, and condition-testing, among other things.
This tutorial was written using the Bourne-Again shell, usually referred to as bash , which is the default shell for most Linux distributions, including Ubuntu, Fedora, and RHEL.
The Command Prompt
When you first login to a server, you will typically be greeted by the Message of the Day (MOTD), which is typically an informational message that includes miscellaneous information such as the version of the Linux distribution that the server is running. After the MOTD, you will be dropped into the command prompt, or shell prompt, which is where you can issue commands to the server.
The information that is presented at the command prompt can be customized by the user, but here is an example of the default Ubuntu 20.04 command prompt:
Here is a breakdown of the composition of the command prompt:
- sammy : The username of the current user
- webapp : The hostname of the server
: The current directory. In bash , which is the default shell, the
Here is an example of what the command prompt might look like, if logged in as root and in the /var/log directory:
Note that the symbol that ends the command prompt is a # , which is the standard prompt symbol for root . In Linux, the root user is the superuser account, which is a special user account that can perform system-wide administrative functions. It is an unrestricted user that has permission to perform any task on a server.
Running Commands
Commands can be issued at the command prompt by specifying the name of an executable file, which can be a binary program or a script. There are many standard Linux commands and utilities that are installed with the OS, that allow you to navigate the file system, install and software packages, and configure the system and applications.
An instance of a running command is known as a process. When a command is executed in the foreground, which is the default way that commands are executed, the user must wait for the process to finish before being returned to the command prompt, at which point they can continue issuing more commands.
It is important to note that almost everything in Linux is case-sensitive, including file and directory names, commands, arguments, and options. If something is not working as expected, double-check the spelling and case of your commands!
Here are a few examples that will cover the fundamentals of executing commands.
Note: If you’re not already connected to a Linux server, now is a good time to log in. If you have a Linux server but are having trouble connecting, follow this link: How to Connect to Your Droplet with SSH.
Without Arguments or Options
To run a command without any arguments or options, type in the name of the command and press Enter .
If you run a command like this, it will exhibit its default behavior, which varies from command to command. For example, if you run the cd command without any arguments, you will be returned to your current user’s home directory. The ls command will print a listing of the current directory’s files and directories. The ip command without any arguments will print a message that shows you how to use the ip command.
Try running the ls command with no arguments to list the files and directories in your current directory (there may be none):
With Arguments
Many commands accept arguments, or parameters, which can affect the behavior of a command. For example, the most common way to use the cd command is to pass it a single argument that specifies which directory to change to. For example, to change to the /usr/bin directory, where many standard commands are installed, you would issue this command:
The cd component is the command, and the first argument /usr/bin follows the command. Note how your command prompt’s current path has been updated.
Try running the ls command to see the files that are in your new current directory.
With Options
Most commands accept options, also known as flags or switches, that modify the behavior of the command. Options follow a command, and are indicated by a single — character followed by one or more options, which are represented by individual upper- or lower-case letters. Some multi-word options can start with — , followed by the flag text.
For an example of how options work, let’s look at the ls command. Here are a couple of common options that come in handy when using ls :
- -l : print a “long listing”, which includes extra details such as permissions, ownership, file sizes, and timestamps
- -a : list all of a directory’s files, including hidden ones (that start with . )
To use the -l flag with ls , use this command:
Note that the listing includes the same files as before, but with additional information about each file.
As mentioned earlier, options can often be grouped together. If you want to use the -l and -a option together, you could run ls -l -a , or just combine them like in this command:
Note that the listing includes the hidden . and .. directories in the listing, because of the -a option.
With Options and Arguments
Options and arguments can almost always be combined, when running commands.
For example, you could check the contents of /home , regardless of your current directory, by running this ls command:
ls is the command, -la are the options, and /home is the argument that indicates which file or directory to list. This should print a detailed listing of the /home directory, which should contain the home directories of all of the normal users on the server.
Environment Variables
Environment variables are named values that are used to change how commands and processes are executed. When you first log in to a server, several environment variables will be set according to a few configuration files by default.
View All Environment Variables
To view all of the environment variables that are set for a particular terminal session, run the env command:
There will likely be a lot of output. Look for the PATH entry:
The PATH environment variable is a colon-delimited list of directories where the shell will look for executable programs or scripts when a command is issued. For example, the env command is located in /usr/bin , and you are able to run it without specifying its full path because its path is in the PATH environment variable.
View the Value of a Variable
The value of an environment variable can be retrieved by prefixing the variable name with a $ . This will expand the referenced variable to its value.
For example, to print out the value of the PATH variable, you may use the echo command:
Or you could use the HOME variable, which is set to your user’s home directory by default, to change to your home directory like this:
If you try to access an environment variable that hasn’t been set, it will be expanded to nothing; an empty string.
Setting Environment Variables
Now that you know how to view your environment variables, you should learn how to set them.
To set an environment variable, all you need to do is start with a variable name, followed immediately by an = sign, followed immediately by its desired value:
Note that if you set an existing variable, the original value will be overwritten. If the variable did not exist in the first place, it will be created.
Bash includes a command called export which exports a variable so it will be inherited by child processes. This allows you to use scripts that reference an exported environment variable from your current session.
You can also reference existing variables when setting a variable. For example, if you installed an application to /opt/app/bin , you could add that directory to the end of your PATH environment variable with this command:
Now verify that /opt/app/bin has been added to the end of your PATH variable with echo :
Keep in mind that setting environment variables in this way only sets them for your current session. This means if you log out or otherwise change to another session, the changes you made to the environment will not be preserved. There is a way to permanently change environment variables, but this will be covered in a later tutorial.
Conclusion
Now that you have begun to learn about the Linux terminal (and a few commands), you should have a good foundation for expanding your knowledge of Linux commands. Read the next tutorial in this series to learn how to navigate, view, and edit files and their permissions.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
Tutorial Series: Getting Started with Linux
If you are new to Linux and its command line interface, it may seem like a daunting task to get started with it. This series will bring you up to speed with essential Linux basics, and provide a solid foundation for working with Linux servers. If you have little to no knowledge about using Linux, this is where you will want to start.
Работа в терминале Linux для начинающих
Все новички Linux уже, наверное, слышали про терминал, или как его еще называют командную строку. Ведь присутствие и сложность терминала — это один из основных аргументов оппонентов Linux. Возможно, вы уже сталкивались с командной строкой в Windows на практике и уже знаете что это такое.
Действительно, в операционной системе Linux есть терминал, где вы можете выполнять нужные вам команды, чтобы очень эффективно управлять своей системой. Но это вовсе не обязательно, многим вполне достаточно графического интерфейса. Сейчас использование терминала отошло на второй план, но он остается основным средством для доступа к удаленным серверам и инструментом для профессионалов.
Терминал Linux намного интереснее, чем командная строка Windows и в этой статье будет подробно рассмотрена работа в терминале Linux для начинающих, а также что такое терминал Linux и собственно, что он из себя представляет.
Что такое терминал Linux?
Применение терминала началось очень давно. Еще до того как была создана DOS и не существовало никакого графического интерфейса. В далеких восьмидесятых годах операционная система Unix только начинала развиваться. Пользователям нужно каким-то образом взаимодействовать с системой и самый простой способ — это использование команд. Вы вводите команду, система вам возвращает ответ.
С тех пор, такой способ ввода использовался во многих системах, в том числе DOS и OS/2 от Apple, пока не был придуман графический интерфейс. Затем текстовый режим терминала был успешно вытеснен, но его до сих пор продолжают использовать там, где это нужно.
Выше, под терминалом мы понимали то место, где можно вводить команды и получать на них ответ от компьютера. Это может быть текстовый режим Linux или же открытое в графическом режиме окно терминала. В Linux часто встречаются слова: консоль, терминал, командная строка, командная оболочка, tty, эмулятор терминала. Все они относятся к терминалу, но означают немного разные вещи. Перед тем как перейти дальше давайте разберемся с терминами, чтобы называть все своими именами.
Под терминалом принято понимать окружение, где можно вводить команды и получать на них ответ, это может быть физический терминал или терминал на компьютере.
Консоль — это физическое оборудование для управления сервером. Когда к серверу нет доступа из сети, для управления им можно использовать только консоль.
TTY — это файл устройства, который создается ядром и предоставляет доступ к терминалу для программ. Это могут быть файлы /dev/tty для постоянных текстовых терминалов и /dev/pts/* для эмуляторов терминалов. Вы можете выполнить команду или отправить сообщение просто записав данные в этот файл, и также получить результат, прочитав данные из этого файла.
Эмулятор терминала — это графическая программа, которая предоставляет вам доступ к tty или pts терминалу. Например, Gnome Terminal, Konsole, Terminix, Xterm и многие другие.
Командная оболочка — устройство tty занимается только передачей и приемом данных, но все эти данные должен еще кто-то обрабатывать, выполнять команды, интерпретировать их синтаксис. Командных оболочек достаточно много, это bash, sh, zsh, ksh и другие, но чаще всего применяется Bash.
Ну и командная строка — это то место куда вы будете вводить свои команды, приглашение терминала для ввода.
Теперь, когда мы разобрались что такое терминал Linux и знаем все основные принципы, перейдем к практике работы с ним.
Как открыть терминал Linux?
Есть несколько способов получить доступ к терминалу. Ваша система инициализации по умолчанию создает 12 виртуальных терминалов. В одном из них — обычно седьмом, запущена ваша графическая оболочка, но все другие могут быть свободно использованы. Для переключения между терминалами можно использовать сочетания Ctrl+Alt+F1-F12. Для авторизации нужно будет ввести логин и пароль.
Это текстовые терминалы без графического интерфейса, в них может быть не совсем удобно работать, но, зато такие терминалы будут полезны, если графический интерфейс не работает.
Второй способ позволяет открыть виртуальный терминал прямо в графическом интерфейсе с помощью эмулятора терминала. Эмулятор терминала linux работает с файлами в каталоге /dev/pts/* и еще называется псевдотерминалом, потому что не использует tty.
В Ubuntu вы можете запустить терминал linux нажав сочетание клавиш Ctrl+Alt+T:
Также его можно найти в меню приложений Dash:
Как видите, открыть командную строку в linux очень просто.
Выполнение команд в терминале
Рассмотрим более подробно терминал Linux для начинающих. Как я уже говорил, терминал и файлы устройств tty отвечают только за передачу данных. За обработку команд отвечает командная оболочка, которой и передаются полученные от пользователя данные.
Вы можете набрать что-либо и убедиться, что это работает:
Чтобы выполнить команду достаточно написать ее и нажать Enter.
Более того, командная оболочка Bash поддерживает автодополнение, поэтому вы можете написать половину команды, нажать TAB и если на такие символы начинается только одна команда, то она будет автоматически дополнена, если же нет, то вы можете нажать два раза TAB, чтобы посмотреть возможные варианты.
Точно такая же схема работает для путей к файлам и параметров команд:
В Windows вы о таком и мечтать не могли. Чтобы выполнить команду можно указать имя ее исполняемого файла или полный путь к нему, относительно корневой или любой другой папки. Важно заметить, что командная оболочка Linux, в отличие от Windows, чувствительна к регистру, а поэтому будьте внимательны при вводе команд и их параметров.
По умолчанию работа в командной строке linux может выполняться с помощью большого количества команд, многие из них, например, для перемещения по каталогам, просмотра содержимого, установки ПО поставляются вместе с системой.
Экземпляр запущенной команды называется процесс. Когда в терминале Linux выполняется одна команда нам нужно подождать ее завершения, чтобы выполнить следующую.
Команды могут выполняться без параметров, что мы видели выше, или же с параметрами, которые позволяют указать данные, с которыми будет работать программа, также есть опции, с помощью которых можно настроить поведение. Большинство стандартных утилит придерживаются такого синтаксиса:
$ команда опции параметр1 параметр2.
Опции часто необязательны и уточняют тот или иной аспект работы программы. Они записываются в форме черточка и символ или двойная черточка и слово. Например -o или —output. Приведем пример для команды ls. Без опций и параметров:
С параметром, указывающим какую папку посмотреть:
С опцией -l, вывести в виде списка:
В с опцией и параметром:
Можно комбинировать две опции:
В основном, это все, что нужно знать про команды, чтобы продуктивно их использовать. Еще можно было бы рассказать про объединение команд и перенаправление вывода одной команды в другую, но это уже отдельная тема.
Выводы
В этой статье была рассмотрена работа в терминале linux для начинающих. Командная строка Linux может показаться сначала очень сложной, но это совсем не так, она намного проще в использовании чем в Windows и позволяет управлять системой более эффективно. Надеюсь, эта статья пролила немного света на эту очень большую тему.
Похожие записи
Оцените статью
alt=»Creative Commons License» width=»» />
Статья распространяется под лицензией Creative Commons ShareAlike 4.0 при копировании материала ссылка на источник обязательна .
Об авторе
Основатель и администратор сайта losst.ru, увлекаюсь открытым программным обеспечением и операционной системой Linux. В качестве основной ОС сейчас использую Ubuntu. Кроме Linux, интересуюсь всем, что связано с информационными технологиями и современной наукой.
18 комментариев к “Работа в терминале Linux для начинающих”
Мне кажется или последние два скрина терминалов не на своем месте?
Абсолютно никакого света! Ёлки-палки, вы можете писать понятнее.
КАК МНЕ ВЫЙТИ — НА РАБОЧИЙ СТОЛ.
Автор все прекрасно обьяснил, посидите еще годик два и сразу начнете понимать! Это очень дружелюбная система
Я конечно всё понимаю, команды там и так далее. Но что делать, если при вводе пароля в терминале банально перестаёт работать ввод любых символов? Даже копирование не помогает.
нет не какой инфы об обновлении системы и её драйверах!
Статья не о чем . Вот по тому научитса работать с Линукс
БОЛЬШАЯ ПРОБЛЕМА ДЛЯ МИЛИОНОВ!
. уета, при чём с амбицией имбицила, опен сорс, впервую очередь позитивное движение, а этот материал, как чемодан безручки, уже нагруженномому пользователю *100000 к карме тебе!
методика подачи материала отсутствует автор полагает что слушатели должны домысливать материал .
но надо сказать , что автор всё таки старался донести свои мысли и знания до слушателей не бывает плохих учеников бываю неважные педагоги
Хочу сказать, что самую главную мысль ты донёс. Терминал в линукс — это мощная среда управления твоей системой. Ты показал что его синтаксис не так уж и сложен, а по поводу детальной разборки всех команд — гугл в помощь.
Спасение утопающего — дело рук самого утопающего. )
Кто хочет понять и научиться, тот поймёт и научится.
Автору — огромный респект за МНОГОЛЕТНИЕ труды!
Это в Windows может быть кнопка под названием «Сделай хорошо!». И винда сделает! Только не факт, что хорошо она сделает ВАМ. ))) У неё свои взгляды на то, что такое хорошо. И они могут не совпадать с вашими.
Linux — философия. Ты получаешь от системы только то, что нужно именно тебе. Без всякого своеволия со стороны ОС. Главное — определится, что тебе нужно и правильно сформулировать.
в Linux все делается через «командную строку»
в Windows- через заднюю ступицу
Да Linux сложен для новичков. Но если захотите разобраться- вы его полюбите.
И полюбите надолго
Да, прошу прощения! Хотел похвалить автора за статью
Эта статья — не первая, которую я прочитал про Терминал, так у меня получилось, и для меня она была полезна, узнал кое-что новое.
Я понял, что пользоваться этой статьёй надо так:
Брать и повторять в своём терминале предлагаемые команды (конечно — со своими именами файлов и каталогов в качестве параметров)
Главное: все эти упоминаемые команды для меня были абсолютно безопасны.
Однако, похоже, что для тех, у кого эта статья оказалась первой про Терминал, не всё так гладко.
Ну, ввожу я команду в Терминал, нажимаю. Enter и появляется копия такой же команды, которую я вставил перед этим, что дальше? Для чего этот терминал нужен?
Мне кажется из многих сайтов о Линукс — этот наиболее дружелюбный и понятный. Автор молодец.
«Еще можно было бы рассказать про объединение команд и перенаправление вывода одной команды в другую». Вот именно про это и надо было рассказать, самое интересное и не написали.
Hello, World! Глубокое погружение в Терминалы
На написание данной статьи меня вдохновила статья об анализе Сишного printf. Однако, там был пропущен момент о том, какой путь проходят данные после того, как они попадают в терминальное устройство. В данной статье я хочу исправить этот недочет и проанализировать путь данных в терминале. Также мы разберемся, чем отличается Terminal от Shell, что такое Pseudoterminal, как работают эмуляторы терминалов и многое другое.
Основы
Давайте для начала разберемся, что такое Terminal, Shell, Console, чем отличается Terminal Emulator от обычного Terminal и почему он так назван. Информации об этом написано уже довольно много, поэтому ничего нового вы здесь не услышите. Почти вся информация здесь была взята из интернета, ссылки приведу в конце статьи. Кто уже знает, что все эти вещи обозначают, может смело пропускать данный раздел.
Terminal
Terminal (терминал) — это комбинация дисплея и клавиатуры, то есть физическое устройство. До того, как терминалы стали именно данной комбинацией, они являлись неким устройством под названием teleprinter (teletype, teletypewriter или TTY сокращенно), то есть комбинацией принтера и клавиатуры. Обычно несколько терминалов подключались к одному и тому же компьютеру. Таким образом возможно было работать нескольким пользователям за одним и тем же компьютером, причем каждому выделялась своя сессия, независимая от других. Терминал был назван так потому, что он находился на конце терминального кабеля (terminal end).
Это Teletype:
А это Terminal:
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 устройства:
Существует 3 типа TTY устройств:
- Console device — обеспечивает работу Virtual Console. Ввод и вывод данного устройства управляется полностью ядром.
- PTY device (псевдотерминал) — обеспечивают работу терминала в оконном интерфейсе. Ввод и вывод данного устройства управляется эмулятором терминала, который работает в пользовательском пространстве.
- Serial device — общается напрямую с железом. Обычно не используется напрямую, а существует как самый нижний уровень в организации архитектуры терминального устройства.
В данной статье мы будем говорить именно о втором типе TTY устройств — псевдотерминалах.
TTY Line Discipline
Начнем рассматривать дисциплину линии TTY устройств.
Первой важной особенностью дисциплиной линии является то, что она отвечает за процессинг ввода/вывода. Это включает в себя, например, обработку управляющих символов (см. Управляющие символы) и форматирование вывода. Например, вы вводите любой текст, но вдруг понимаете, что ошиблись в написании чего-то и хотите это стереть — именно тут в дело вступает дисциплина линии.
Разберем подробно, что именно происходит, когда мы работаем в Bash, запущенном в терминале. По умолчанию TTY устройство работает в каноничном режиме с включенным эхо (echoing). Эхо — это отображение введенных вами символов на экране.
Когда мы вводим, к примеру, символ a , данный символ посылается в TTY устройство, но перехватывается дисциплиной линии TTY устройства. Она читает символ в свой внутренний буфер, видит, что включен режим echo и выводит символ на экран. В это время еще ничего не доступно для чтения в программе, к которой прикреплено терминальное устройство. Пусть мы нажимаем backspace на клавиатуре. Символ ^? снова перехватывается дисциплиной линии, и последняя, понимая, что пользователь хочет стереть последний введенный символ, удаляет данный символ из своего внутреннего буфера и стирает этот символ также с экрана. Теперь, если мы нажмем Enter, TTY Line Discipline наконец пошлет в буфер чтения терминального устройства все, что было записано раннее в внутренний буфер дисциплины, включая LF. При этом, на экран выводятся символы CR и LF для того, чтобы перевести курсор на новую строку — это форматирование вывода.
Так работает каноничный режим — передает все введенные символы в устройство только после нажатия Enter , производит процессинг управляющих символов и форматирует вывод.
TTY Line Editing
TTY Line Editing — это тот компонент, который отвечает за процессинг ввода в дисциплине линии. Следует сказать, что Line Editing — это общее понятие и относится оно к процессингу ввода. Например, Bash и Vim имеют свой Line Editing.
Мы можем контролировать настройки дисциплины линии текущего TTY устройства с помощью программы stty. Давайте немного поэкспериментируем.
Откройте Bash или любой другой Shell и введите:
Теперь попробуйте что-нибудь ввести — и вы не увидите вашего ввода (не беспокойтесь, вы все еще можете передавать ввод в программу). Вы только что отключили эхо — то есть отображение введенных символов на экране. Теперь введите:
Попробуйте что-нибудь вводить. Вы видите, как нарушается вывод. Но для большего эффекта давайте зайдем в Dash — введите /bin/sh . Теперь попробуйте вводить специальные символы (клавиша Ctrl + любой символ на клавиатуре) или же просто нажать Enter . Вы недоумеваете — что это за странные символы на экране? Дело в том, что мы, зайдя в самый простой Shell, кроме Line Editing самой дисциплины отключили также Line Editing Bash, и теперь можем вовсю наблюдать эффект включения raw режима дисциплины линии. Данный режим совершенно не производит процессинг ввода и не форматирует вывод. Зачем raw режим нужен? Например, для Vim: он открывается во всё окно терминала и производит сам процессинг ввода, хотя бы для того, чтобы специальные символы дисциплины линии не пересекались с специальными символами самого Vim.
Для еще большего понимания давайте рассмотрим кастомизацию управляющих символов. В этом нам поможет команда stty <control-character> <string> .
Введите в Bash:
Теперь управляющий символ erase будет назначен на символ 0 . Кнопка backspace обычно имеет значение ^? , но теперь данный специальный символ будет передаваться в буфер чтения PTS устройства буквально — попробуйте сами. Стирать символы же теперь вы можете с помощью кнопки 0 на клавиатуре, ведь вы сами попросили tty line discipline распозновать введенный символ как управляющий символ erase . Вернуть обратно настройку вы можете с помощью команды stty erase ^\? или просто закрытием терминала, ведь мы влияли только на текущее tty устройство.
Больше информации вы сможете найти в man stty.
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 устройство.
Вы можете сами посмотреть, куда направлены стандартные потоки вывода терминала, с помощью команды ls -la /proc/self/fd :
PTS устройство находится по пути /dev/pts/N, а путь к PTM устройству нас абсолютно не интересует. Дело в том, что GNOME Terminal Server уже имеет файловый дескриптор открытого PTM устройства и ему не требуется путь к нему, однако в дочернем процессе мы должны открыть PTS устройство на стандартных потоках вывода с помощью вызова функции open() , которая требует путь к файлу.
Помните, я сказал, что программа, использующая PTS устройство, только думает, что она общается напрямую с терминалом? Дело в том, что PTS также является терминальным устройством (TTY устройством), но разница между PTS устройством и действительным TTY устройством в том, что PTS устройство ввод получает не с клавиатуры, а с master устройства, а вывод идет не на дисплей, а на master устройство. Именно поэтому псевдотерминал назван так — псевдотерминал лишь имитирует (опять??) терминал. Разница между эмулятором терминала и псевдотерминалом в том, что эмулятор терминала — это лишь графическая программа, позволяющая запускать терминал прямо внутри оконного интерфейса, но реализована эта возможность с помощью псевдотерминала.
То, что PTS устройство является TTY устройством — это очень важно. Вот почему:
- Программе, к которой прикреплено терминальное устройство, доступны все возможности обычного терминала. Например: отключение эха, отключение/включение каноничного вида.
- Программа, зная, что к ней прикреплен терминальное устройство (говорится, что программа имеет управляющий терминал), может работать в интерактивном режиме и просить у пользователя ввода. Например, спрашивать логин и пароль.
- Здесь также существует TTY Line Discipline, поэтому мы имеем возможность обрабатывать управляющие символы до того, как они дойдут до программы, а также форматировать вывод программы.
PTM устройство также является TTY устройством, но это не играет никакой роли, так как оно не используется в роли управляющего терминала. Более того, дисциплина линии PTM устройства установлена в raw режим, поэтому процессинг при передаче данных от PTS к PTM устройству не производится. Однако, вызовы read() и write() из пользовательского пространства все равно сперва обслуживаются дисциплиной линии на обоих устройствах. Данный момент сыграет еще большую роль, как мы увидим позднее.
Процесс общения GNOME Terminal Server и запущенной внутри терминала программы выглядит следующим образом:
Следует поподробнее рассмотреть роль, которую играет дисциплина линии при общении между обеими частями псевдотерминала. Здесь дисциплина линии отвечает за процессинг данных, переходящих от PTM к PTS устройству, а также за доставку данных из одной части псевдотерминала в другую. Когда мы находимся в драйвере PTS устройства, мы задействуем дисциплину линии PTM устройства, и наоборот.
Виртуальные устройства
Вы, наверное, могли подумать, что можете открыть файл по пути /dev/pts/N и писать или читать данные из него, как из обычного текстового файла? Да, все устройства в Unix-подобных системах являются файлами благодаря фундаментальному принципу Unix, который гласит, что все является файлом. Однако, никакие специальные файлы устройств (англ. — device file) не являются текстовыми файлами. Такие устройства называются виртуальными устройствами (virtual device) — то есть существуют исключительно в памяти, а не на диске.
Не стоит пытаться открывать данные файлы как обычные текстовые файлы. Однако, вы можете использовать эти устройства через операции write() и read() , вызов которых обслужит драйвер устройства. Давайте попробуем сделать это.
Откройте два окна терминала и введите в каждом команду tty . Данная команда покажет, какое TTY устройство обслуживает текущий активный терминал. Теперь введите echo «Hello, World!» > /dev/pts/N в первом окне терминала, где N — это индекс PTS устройства второго окна, переключитесь на второе окно — и вы увидите ваш ввод с первого окна. Сейчас вы записали данные в PTS устройство второго окна так, как будто бы это сделала программа, работающая в том терминале.
Устройство псевдотерминала
Мы все ближе приближаемся к заключительной части статьи, но перед этим заглянем «под капот» Linux — рассмотрим устройство псевдотерминала на уровне ядра. Будет много кода, но я постараюсь объяснять каждый приведенный блок кода максимально подробно, сокращать неважные детали и идти последовательно.
Перед началом введем так называемую «корзину компонентов». По мере продвижения по ядру, мы будет добавлять в нее всё больше компонентов и находить связь между ними. Надеюсь, это еще лучше поможет понять устройство псевдотерминала. Приступим.
Когда Linux запускается, он загружает необходимые драйверы устройств. Такой драйвер имеется и у нашего псевдотерминала. Его регистрация начинается с вызова данной функции:
Для всех современных систем будет вызвана функция unix98_pty_init() :
Здесь нас интересует 3 вещи:
- Вызовы tty_set_operatons для драйвера pty master и pty slave устройств.
- Функция ptmx_open , которая отвечает за создание обоих частей псевдотерминала при открытии специального устройства /dev/ptmx. Важно: /dev/ptmx — это не PTM устройство, а всего лишь интерфейс для создания нового псевдотерминала.
- Регистрация драйвера PTM и PTS устройств.
Пойдем по порядку:
1. tty_set_operations
Функция tty_set_operations() всего лишь устанавливает таблицу функций для текущего драйвера:
Структура tty_operations — это таблица функций, которая используется для доступа к функциям драйвера TTY устройства.
Выделю самое главное в структурах pty_unix98_ops и ptm_unix98_ops , которые являются таблицей функций для соответствующих частей псевдотерминала:
Здесь можете наблюдать уже знакомую по статье о Сишном printf функцию pty_write — к ней мы вернемся чуть позднее.
Давайте добавим данную структуру в нашу корзину компонентов:
Как видите, основные методы обоих драйверов совсем не отличаются. Кстати, заметьте, что отсутствует функция для read() операции — нет ничего похожего на pty_read() . Дело в том, что чтение будет обслуживаться исключительно дисциплиной линии. Таким образом, мы узнаём о второй важной особенности дисциплины линии — чтение данных с TTY утройства.
2. ptmx_open
Теперь перейдем к ptmx_open():
Нас интересует функция tty_init_dev() , где первым аргументом является драйвер PTM устройства, а вторым — индекс устройства. Здесь мы покидаем зону ответственности PTY драйвера и переходим к файлу, который отвечает только за общие TTY устройства и ничего не знает о нашем псевдотерминале.
Сначала разберем функцию alloc_tty_struct() :
Единственное, что нас здесь интересует, это функция tty_ldisc_init() :
Которая вызывает tty_ldisc_get() :
Итак, мы рассмотрели вызов функции alloc_tty_struct() , которая создает структуру tty_struct вместе с дисциплиной линии — структурой tty_ldisc. Обе структуры имеют ссылки друг на друга. Давайте познакомимся с данными структурами поближе.
- tty_struct — это структура для доступа к драйверу TTY устройства и некоторым другим полям. Выглядит она следующим образом:
- tty_ldisc — это структура для дисциплины линии TTY устройства. Состоит она всего из двух полей и выглядит следующим образом:
Вроде бы ничего сложного? Давайте добавим все рассмотренные до этого момента структуры в нашу корзину и свяжем их таким же образом, как они связаны в коде:
Но мы создали tty_struct всего лишь для PTM устройства. А что же о PTS устройстве? Для этого вернемся к функции tty_init_dev() и вспомним о том, что дальше нас ожидает вызов функции tty_driver_install_tty() :
Комментарий подсказывает нам, что данный метод ответственен за создание различных дополнительных структур. PTS устройство и будет являться нашей дополнительной структурой. Признаюсь, это было для меня крайне удивительно, ибо это, черт возьми, целое устройство, а не просто какая-то дополнительная структура! Но мы то с вами понимаем, что все устройства — это всего лишь какие-то структуры, так что идем дальше. Хорошо, что такое здесь driver->ops->install? Для этого посмотрим на таблицу функций для PTM драйвера ещё раз:
И поймем, что нас интересует функция pty_unix98_install() :
Которая вызывает функцию pty_common_install() :
Мы видим, что для PTS устройства создается абсолютно такая же структура tty_struct за исключением того, что в ней будет находиться драйвер PTS устройства. Обе структуры хранят указатели друг на друга для общения между собой. Добавляем tty_struct для PTS устройства в нашу корзину.
Регистрация драйвера
Мы не будем рассматривать весь процесс регистрации драйвера, так как нас интересует только установка таблицы функций для файла TTY устройства (ведь мы должны как-то получить доступ к самому устройству при работе с файлом?).
Это — таблица функций, которая будет установлена для файла как PTM, так и PTS устройства:
Мы не будем добавлять данную структуру в нашу корзину, ибо она в принципе то и не относится к устройству псевдотерминалов и служит лишь для доступа к TTY устройству.
Готово. Мы рассмотрели процесс создания обоих устройств, который будет произведен при открытии мультиплексора /dev/ptmx. Таким образом, включая второе PTS устройство, которое имеет точно такое же строение, как и PTM устройство, общая картина строения псевдотерминала складывается следующая:
Hello, World!
Ну вот мы и подошли к самому главному. В данной главе мы полностью разберем путь нашей строки «Hello, World!», отправленной из простой Си программы в терминальное устройство.
Итак, наша строка «Hello, World!» отправляется в увлекательное путешествие. На самом деле, программа не знает ничего, кроме того, что она пишет в стандартный поток вывода. Ей больше нет разницы, куда этот вывод пойдет. Направьте stdout в /dev/null — и вывод вообще не будет нигде отображаться. Здесь я не буду рассказывать о вызовах библиотечных Си функций, а начнем сразу с файловой системы Linux.
Так как каждое устройство в Unix является файлом с определенными для него функциями write(), read(), close() и прочими, то при вызове write() на /dev/pts/0 мы попадаем в общую для всех файлов функцию __vfs_write() :
Здесь мы вызываем операцию write() из таблицы функций для текущего файла. Как вы помните, таблица функций была установлена при регистрации драйвера и выглядела она следующим образом:
Данная функция получает структуру tty_struct для текущего файла TTY устройства, а потом достает из нее дисциплину линии и вызывает функцию write() для нее. Таблица функций дисциплины линии выглядела следующим образом:
Переходим к функции n_tty_write() :
Итак, строка «Hello, World!» наконец отправилась в write() функцию драйвера PTS устройства. Найдем эту функцию в таблице функций драйвера:
Давайте здесь остановимся и проследим наш путь до этого места:
Вроде бы ничего не упустили. Итак, буфер передается в очередь ввода на PTM устройство. Разберемся, как именно это происходит.
Для начала, следует познакомить вас с новой структурой данных под названием flip buffer. Flip buffer — это структура данных, состоящая из двух массивов. Когда tty driver получает новые данные, он сохраняет их в первом массиве. Когда массив заполняется, ожидающая данных сторона будет об этом уведомлена и сможет прочитать данные из этого массива. Если в будущем появятся новые данные, они сохранятся уже во второй массив для того, чтобы не перезаписать читающиеся другой стороной данные. Когда и этот массив заполняется, ожидающая данных сторона снова будет уведомлена, а новые данные в следующий раз будут снова записываться в первый массив. Именно из-за такой логики данная структура данных и названа flip buffer — потому что данные перемещаются между массивами (наверное, здесь лучше подойдет какое-то другое слово, но я не знаю хорошего перевода для слова flip).
Не будем долго тянуть и снова идти по цепочке вызовов, так что сразу перейдем к нужной функции. Вызов tty_insert_flip_string() в итоге перетекает в вызов функции под названием tty_insert_flip_string_fixed_flag() , в которой и происходит основная работа по передаче данных в PTM устройство:
На самом деле, flip buffer был замёнен новой имплементацией в новых версиях ядра, однако поведение буфера осталось почти таким же, а все функции остались совместимы с раннее реализованными драйверами. Не стоит сильно вникать в устройство данного буфера, ясно одно — в конце концов данные будут перемещены в PTM устройство, а после окончания записи ожидающая сторона будет уведомлена о готовых для чтения данных.
Итак, наша строка «Hello, World!» оказалась в PTM устройстве. В это время GNOME Terminal Server заблокирован на вызове poll() (техника мультиплексирования I/O) и ожидает новых данных на любом из master устройств. Вы думаете, сейчас он проснется и прочитает новые данные на устройстве? Как бы не так. Когда я говорил об ожидающей стороне, я говорил о дисциплине линии, ведь это именно её задача — принимать ввод и производить его процессинг при необходимости.
Дисциплина линии будет уведомлена о новых данных с помощью вызова функции tty_flip_buffer_push() (в том же pty_write):
Функция tty_schedule_flip() , в свою очередь, планирует задачу по доставке данных в дисциплину линии:
Я не знаю, что здесь подразумевается под work (предположу, что это какая-то внутренняя структура ядра для планировки различных задач) и какой компонент ядра отвечает за планировку, но из комментариев ясно следующее — когда задача начнет выполняться, доставку организует функция flush_to_ldisc() :
Функция receive_buf() через цепочку вызовов в итоге перетекает в вызов функции __receive_buf() , которая диспатчит работу по процессингу ввода:
Все функции, начинающиеся с n_tty_receive_buf (кроме тех, где есть суффикс _raw) производят процессинг данных и записывают данные в буфер под названием read_buf, который и является основным буфером для чтения с TTY устройства. Так как дисциплина линии для PTM устройства установлена в raw режим, то процессинг не будет произведен и данные сразу запишутся в read_buf. Однако, если бы мы разбирали доставку данных от PTM к PTS устройству, то процессинг был бы произведен.
Опишу полную цепочку вызовов до конечного вызова, включая пропущенные вызовы:
Заметьте, никакая функция PTM драйвера при перемещении данных не была использована — вся работа произошла в дисциплине линии и драйвере PTS устройства.
Можете выдохнуть: данные наконец записаны в конечный буфер PTM устройства. Теперь GNOME Terminal Server просыпается и читает нашу строку «Hello, World!», вызывая read() на PTM устройстве. Вызов read() по аналогии с write() перехватывается дисциплиной линии — методом n_tty_read() . В этой функции нет ничего интересного, кроме того, что она просто переместит данные из буфера в ядре — read_buf — в пользовательский буфер. Далее GNOME Terminal Server передает строку в X Server, который отобразит её на дисплей.
Таким образом, наша строчка «Hello, World!» проходит следующий путь:
Заключение
Подведем итог. В данной статье мы узнали:
- Как работают эмуляторы терминалов
- Что такое виртуальные устройства
- Что такое TTY устройства
- Как устроены псевдотерминалы
- Какой путь проходят данные, начиная с обычной Си программы и до дисплея
На этом все, спасибо за внимание! Если у вас возникли какие-нибудь вопросы — смело задавайте их в комментариях, буду рад ответить!