1. Архитектура командной оболочки и интерпретаторы
Архитектура командной оболочки и интерпретаторы
Когда вы открываете терминал и видите мигающий курсор, за этим простым действием стоит сложная цепочка взаимодействий между ядром операционной системы, драйверами устройств и программой-оболочкой. Понимание этой цепочки — не академическое упражнение, а практическая необходимость: именно от архитектуры оболочки зависит, почему одни команды работают мгновенно, а другие «зависают», почему переменные окружения ведут себя по-разному в разных сессиях и почему скрипт, написанный для Bash, ломается в Dash.
Ядро, оболочка и терминал: три слоя взаимодействия
Ядро (kernel) — это программа, которая управляет всеми ресурсами компьютера: процессором, памятью, дисками, сетью. Оно не имеет пользовательского интерфейса. Чтобы человек мог с ним взаимодействовать, нужен посредник.
Командная оболочка (shell) — это именно такой посредник. Она принимает текстовые команды от пользователя, интерпретирует их и передаёт ядру через системные вызовы (system calls). Результат ядро возвращает оболочке, а та — пользователю.
Терминал (terminal emulator) — это программа, которая эмулирует физический терминал прошлого века. Она отображает символы, обрабатывает ввод с клавиатуры и управляет окном. Терминал сам по себе ничего не исполняет — он лишь передаёт потоки данных между пользователем и оболочкой.
Представьте это как почтовую систему: терминал — это почтовый ящик, оболочка — почтальон, который читает письма и разносит их, а ядро — почтовое отделение, которое обрабатывает отправления. Почтальон не знает, как работает сортировочная машина, а почтовое отделение не знает, кто написал письмо.
Семейство оболочек Bourne и C
Исторически сложились два семейства оболочек. Первое — Bourne shell (sh), созданный Стивеном Боурном в 1979 году. Его синтаксис стал стандартом для написания сценариев. Второе — C shell (csh), чей синтаксис напоминает язык C. Сегодня в системном администрировании доминирует первое семейство.
| Оболочка | Имя | Особенности |
|----------|-----|-------------|
| Bourne Again Shell | Bash | Стандарт большинства дистрибутивов Linux, расширенный синтаксис |
| Z Shell | zsh | Улучшенное автодополнение, плагины, используется в macOS по умолчанию |
| Dash | dash | Минималистичная, быстрая, используется как /bin/sh в Debian/Ubuntu |
| Korn Shell | ksh | Компромисс между sh и csh, популярен в коммерческих Unix |
Узнать текущую оболочку можно командой echo 0 — оболочку, которая выполняет текущий процесс.
Процесс инициализации: login и non-login сессии
Когда пользователь входит в систему, оболочка проходит процесс инициализации — последовательность чтения конфигурационных файлов. Этот процесс различается в зависимости от типа сессии.
Login-сессия возникает при входе в систему: через консоль (Ctrl+Alt+F1), SSH или графический терминал с явной аутентификацией. Bash в этом случае читает файлы в такой последовательности:
/etc/profile — глобальная конфигурация для всех пользователей~/.bash_profile, ~/.bash_login или ~/.profile — первый существующий из трёхNon-login сессия — это когда вы открываете новый терминал в графической среде или запускаете оболочку из другой оболочки. Здесь Bash читает только ~/.bashrc.
Это различие объясняет частую проблему: вы добавили переменную в .bashrc, но при входе по SSH она не работает — потому что login-сессия читает .profile, а не .bashrc. Решение — добавить в .profile строку source ~/.bashrc.
Внутренние и внешние команды
Оболочка различает два типа команд. Встроенные команды (builtins) исполняются непосредственно процессом оболочки без создания нового процесса. К ним относятся cd, export, alias, echo, type. Внешние команды — это отдельные исполняемые файлы в каталогах, перечисленных в переменной PATH — это список каталогов, разделённых двоеточиями, в которых оболочка ищет исполняемые файлы. Порядок каталогов имеет значение: оболочка останавливается на первом совпадении. Поэтому добавление /usr/local/bin в начало $PATH позволяет переопределить системные утилиты локальными версиями.
Режимы интерактивного ввода
Оболочка работает в двух режимах обработки ввода. Канонический режим (canonical mode) буферизирует ввод до нажатия Enter — оболочка получает готовую строку. Неканонический режим (non-canonical mode) передаёт каждый символ немедленно — используется в программах вроде vim или top.
Управляет этим драйвер терминала line discipline — промежуточный слой между клавиатурой и приложением. Он обрабатывает специальные символы: Ctrl+C (SIGINT), Ctrl+Z (SIGTSTP), Backspace. Именно поэтому нажатие Ctrl+C в оболочке прерывает текущую команду, а не вставляет символ — line discipline перехватывает его до того, как он достигнет оболочки.
Понимание этой архитектуры позволяет эффективно диагностировать проблемы: если терминал «глючит» после прерванной программы, команда reset сбрасывает настройки line discipline. Если скрипт ведёт себя непредсказуемо — проверьте, какую оболочку указывает shebang-строка (#!/bin/bash или #!/bin/sh), потому что /bin/sh в разных дистрибутивах может указывать на разные интерпретаторы.