Командная оболочка sh
sh (от англ. shell — оболочка) — это командная оболочка операционной системы, предназначенная для интерпретации и выполнения команд, вводимых пользователем или содержащихся в сценариях (скриптах). sh является одной из старейших и наиболее фундаментальных оболочек в Unix-подобных системах, служащей стандартным интерфейсом для взаимодействия пользователя с ядром операционной системы. В современном контексте под sh часто понимают не только оригинальную оболочку, но и её совместимые реализации, соответствующие стандарту POSIX.
История
Происхождение в Bell Labs
Первая командная оболочка Unix была создана Кеном Томпсоном в 1971 году для первой версии операционной системы Unix в исследовательском центре Bell Labs. Эта оболочка, известная как Thompson shell, была простой программой, которая запускала другие программы и не поддерживала сценарии. В 1975 году Стивен Борн (Stephen Bourne) разработал новую оболочку, которая получила название Bourne shell (sh). Она была включена в 7-ю версию Unix и стала стандартной оболочкой для многих коммерческих Unix-систем. Bourne shell ввёл такие ключевые элементы, как управляющие структуры (if, for, while), перенаправление ввода-вывода, подстановку команд и переменные среды.
Стандартизация и развитие
В 1980-х годах наряду с Bourne shell появились альтернативные оболочки, такие как C shell (csh) от Билла Джоя и Korn shell (ksh) от Дэвида Корна. Korn shell (ksh) была обратно совместима с sh, но добавляла функциональность, заимствованную из csh и других источников. В 1989 году Брайан Фокс выпустил GNU Bourne-Again SHell (bash) для проекта GNU, который сочетал синтаксис sh с расширениями из ksh и csh. bash стал оболочкой по умолчанию во многих дистрибутивах Linux и в macOS до 2019 года.
В 1992 году Институт инженеров по электротехнике и электронике (IEEE) выпустил стандарт POSIX.2, который определил минимальные требования к командной оболочке, основанные на поведении Korn shell. Этот стандарт, известный как POSIX shell, стал эталоном для совместимости. Современные реализации sh, такие как dash (Debian Almquist shell), ориентированы на строгое соответствие POSIX и высокую скорость выполнения.
Архитектура и принципы работы
Интерпретатор команд
sh является интерпретатором командного языка. При запуске она читает команды из стандартного ввода (обычно с клавиатуры) или из файла-сценария, разбивает их на лексемы, выполняет подстановки (переменных, команд, арифметических выражений) и запускает соответствующие программы. После завершения каждой команды оболочка выводит приглашение (prompt) и ожидает следующую команду.
Основные компоненты
- Встроенные команды (builtins): команды, реализованные непосредственно в коде оболочки (cd, echo, exit, export, source). Они выполняются без запуска отдельного процесса, что повышает производительность.
- Внешние команды: программы, расположенные в файловой системе (например, /bin/ls, /usr/bin/grep). sh ищет их в каталогах, перечисленных в переменной PATH.
- Переменные среды: именованные строки, передаваемые дочерним процессам (PATH, HOME, USER). Переменные оболочки существуют только внутри текущего сеанса.
- Управляющие структуры: конструкции для ветвления (if-then-else, case) и циклов (for, while, until).
- Функции: именованные блоки команд, которые можно вызывать по имени.
- Перенаправление ввода-вывода: операторы <, >, >>, |, позволяющие перенаправлять потоки данных между командами и файлами.
Процесс выполнения
- sh читает строку ввода.
- Выполняет синтаксический разбор: выделяет команды, операторы, аргументы.
- Производит подстановки: заменяет переменные ($VAR), подставляет результат команд ($(cmd)), выполняет арифметику ($((expr))).
- Разделяет строку на отдельные команды (если используется ; или конвейер |).
- Для каждой команды: если это встроенная — выполняет её; если внешняя — порождает дочерний процесс с помощью системного вызова fork() и exec().
- Ожидает завершения дочернего процесса и получает код возврата.
Стандарты и реализации
POSIX shell
Стандарт POSIX.2 (IEEE 1003.2) описывает синтаксис и поведение командной оболочки. Основные требования включают поддержку:
- Управляющих структур (if, for, while, case).
- Функций с именованными параметрами.
- Перенаправления ввода-вывода (включая здесь-документы).
- Подстановки команд ($(cmd) и обратные кавычки
cmd). - Переменных позиционных параметров ($1, $2, …) и специальных переменных ($?, $#, $@).
- Арифметических выражений ($((expr))).
Основные реализации
- Bourne shell (sh): оригинальная реализация, использовавшаяся в Unix System V. В современных системах почти не встречается в чистом виде.
- Korn shell (ksh): коммерческая оболочка от AT&T, обратно совместимая с sh. Существуют открытые версии (pdksh, mksh).
- Bash (GNU Bourne-Again SHell): наиболее распространённая оболочка в Linux. При запуске под именем sh работает в режиме совместимости с POSIX (с некоторыми отличиями).
- Dash (Debian Almquist shell): быстрая и минималистичная оболочка, строго соответствующая POSIX. Используется как /bin/sh в Debian и Ubuntu для ускорения загрузки системы.
- Zsh (Z shell): расширенная оболочка с мощными возможностями автодополнения и настройки, совместимая с sh при включении режима POSIX.
- BusyBox sh: компактная реализация sh, входящая в состав BusyBox, используемая во встраиваемых системах и минималистичных дистрибутивах.
Синтаксис и основные конструкции
Команды и аргументы
Команда состоит из имени программы и списка аргументов, разделённых пробелами: `` ls -l /home/user ``
Переменные
Присваивание: VAR=value (без пробелов вокруг =). Использование: $VAR или ${VAR}. Специальные переменные: $? (код возврата последней команды), $# (количество аргументов сценария), $@ (все аргументы), $$ (PID текущего процесса).
Управляющие структуры
``` if [ условие ]; then команды elif [ другое условие ]; then команды else команды fi
for var in список; do команды done
while [ условие ]; do команды done
case $var in pattern1) команды ;; pattern2) команды ;; *) команды по умолчанию ;; esac ```
Функции
`` myfunc() { local var=1 echo "Аргумент: $1" return 0 } ``
Перенаправление
cmd > file— вывод в файл (перезапись).cmd >> file— вывод в файл (добавление).cmd < file— ввод из файла.cmd1 | cmd2— конвейер: вывод cmd1 становится вводом cmd2.cmd 2>&1— перенаправление stderr в stdout.cmd &> file— перенаправление stdout и stderr в файл.
Подстановка команд
``` result=$(ls -l)
или
result=ls -l ```
Применение
Системное администрирование
sh является основным инструментом для автоматизации задач в Unix-подобных системах. Сценарии на sh используются для:
- Запуска и остановки служб (init-скрипты, systemd-сервисы).
- Резервного копирования данных.
- Мониторинга системных ресурсов.
- Настройки сети и устройств.
- Управления пользователями и правами доступа.
Разработка программного обеспечения
Сценарии sh применяются для сборки проектов (Makefile, configure-скрипты), развёртывания приложений, тестирования и CI/CD-пайплайнов. Многие инструменты, такие как autoconf, генерируют сценарии на sh для автоматической конфигурации программного обеспечения.
Встраиваемые системы
В минималистичных средах, таких как OpenWrt, Alpine Linux или BusyBox, sh (часто в виде ash или dash) является единственной доступной оболочкой. Её малый размер и соответствие POSIX делают её идеальной для устройств с ограниченными ресурсами.
Интерактивная работа
Хотя sh уступает bash или zsh по удобству для интерактивного использования (отсутствие автодополнения, истории команд по умолчанию), она остаётся стандартным средством для административных задач в «голых» окружениях, например, при восстановлении системы.
Критика и ограничения
- Ограниченные возможности программирования: sh не поддерживает массивы (за исключением позиционных параметров), ассоциативные массивы, арифметику с плавающей запятой, объектно-ориентированные конструкции. Это затрудняет сложные вычисления.
- Уязвимости безопасности: неправильное использование переменных (например, отсутствие кавычек) может привести к подстановке команд или раскрытию файлов. Сценарии sh подвержены атакам через переменные среды (Shellshock, CVE-2014-6271).
- Производительность: из-за интерпретируемого характера и частого порождения процессов sh медленнее компилируемых языков или современных интерпретаторов (Python, Perl) для сложных задач.
- Отсутствие стандартных библиотек: в sh нет встроенной поддержки работы с сетью, JSON, XML, регулярными выражениями (кроме базовых в grep/sed).
Влияние
sh стала основой для всех последующих командных оболочек Unix-подобных систем. Её синтаксис и концепции (перенаправление, конвейеры, переменные среды) были заимствованы и адаптированы в Windows PowerShell, командной строке OS/2 и других системах. Стандарт POSIX shell обеспечивает переносимость сценариев между различными операционными системами, включая Linux, macOS, BSD и коммерческие Unix.
Источники
- The Unix Programming Environment — Brian W. Kernighan, Rob Pike (1984).
- Bourne Shell Programming — Stephen Bourne (1978).
- IEEE Std 1003.1-2017 — POSIX.1-2017, Shell and Utilities.
- Advanced Programming in the UNIX Environment — W. Richard Stevens, Stephen A. Rago (2013).
- Документация GNU Bash (GNU Project).
- dash(1) — man-страница Debian Almquist Shell.
BFOmetr — база данных и аналитика по компаниям России.
На главную BFOmetr →