Командная оболочка Unix
Командная оболочка Unix (англ. Unix shell) — это традиционный пользовательский интерфейс в операционных системах Unix и Unix-подобныхах. Пользователь вводит команды в строке приглашения, а компьютер немедленно выполняет их. Поэтому также используется термин интерпретатор командной строки[1]. Термин «shell» в этом контексте был введён в 1964/1965 годах Луи Пузеном, а его концепции реализованы Глендой Шредер (Glenda Schroeder) для Multics.
Обычно в Unix пользователь может выбрать из нескольких командных оболочек. Все распространённые оболочки Unix обладают полноценными средствами скриптовых языков: они позволяют программировать и автоматизировать задачи. Главное отличие от чистых скриптовых языков, например, Perl, awk — наличие специализированных возможностей для интерактивного взаимодействия: от вывода приглашения до редактирования введённых команд и управления заданиями.
В отличие от интерпретаторов командной строки в некоторых других ОС, например, VMS, оболочки Unix являются обычными пользовательскими программами без особых привилегий.
Общие сведения
После входа в систему оболочка запускается процессом login и принимает команды пользователя. Команды делятся на встроенные (реализованные внутри оболочки, например cd) и внешние — те, что ищутся и запускаются из файловой системы.
Большинство актуальных командных оболочек Unix предоставляют следующие возможности:
- запуск команд;
- использование шаблонов имён файлов (wildcard, «глоб», globs) как аргументов;
- условные операторы (
if,case) и циклы (while,for); - встроенные команды (
cd,read); - внутренние переменные (например,
$HOME); - управление переменными окружения для дочерних процессов;
- перенаправление ввода/вывода;
- параллельный запуск процессов, объединение их через конвейеры (pipes);
- запуск процессов в фоновом режиме.
Современные оболочки дополнительно предоставляют:
- автодополнение команд, имён файлов и переменных (completion system);
- редактирование командной строки (command line editing);
- историю команд — повтор и редактирование предыдущих (command history);
- останов и возобновление процессов (job control);
- перемещение процессов между передним планом и фоном (job control);
- встроенные средства для вычислений (
$((2+2))); - встроенные команды для тестирования свойств файлов (
test).
Для отмены выполнения команды оболочка использует возможности драйвера терминала. Обычно ожидание выполнения команды прекращается по сочетанию клавиш Ctrl+C, что регистрируется драйвером устройства.
Командные оболочки Unix используют архитектуру системы: реализуют только базовые возможности, а расширяют их за счёт внешних команд — через развитые механизмы ввода/вывода и конвейеров. В Unix имеются специализированные команды для работы с текстовыми файлами: поиск, редактирование, замена, подсчёт слов и символов, перевод символов, обрезка строк и др.
Скрипты оболочки (shell scripts) — это текстовые файлы, содержащие небольшие программы. Пользователь пишет такие скрипты, оболочка читает и исполняет их. Если вам, например, часто нужно вручную последовательно вводить пять команд, их можно собрать в скрипт и запускать одной командой. Все команды, которые можно ввести вручную, могут быть записаны в скрипт, и наоборот.
Пример скрипта, считающего от одного до ста:
#!/bin/sh
I=1 # Устанавливаем переменную I в 1
while test $I -le 100 # Цикл while, команда test: I<=100
do
echo $I # Команда echo, выводит значение I
I=$(expr $I + 1) # Команда expr, новое значение I
done
Та же последовательность команд в одну строку:
I=1; while test $I -le 100; do echo $I; I=$(expr $I + 1); done
В новых версиях оболочки Bourne и во многих современных командах test и echo реализованы внутри оболочки для повышения эффективности.
Скриптовый файл можно сделать исполняемым командой chmod +x. Скрипт будет работать как обычная команда, однако запуск с повышенными привилегиями часто ограничен.
Если исполняемый файл Unix начинается с #! (shebang), большинство ОС используют следующую за ней строку как указание, каким интерпретатором выполнять скрипт — независимо от интерактивно используемой оболочки вызывающего. Однако этот механизм не входит в стандарт Portable Operating System Interface (POSIX).
При загрузке Unix-систем используются также скрипты оболочки. В BSD-системах для этого запускается /etc/rc, который инициализирует файловую систему, фоновый запуск процессов и др. В Unix System V используется sysinit как набор нескольких скриптов. В Linux распространён systemd, который заменяет скрипты декларативными конфигурационными файлами.
В ряде Unix-команд оболочечные скрипты неотличимы от программ на этапе использования. Некоторые команды, например, man — просмотр онлайн-справки, cc — вызов цепочки компилятора, ассемблера, компоновщика, во многих Unix-системах реализованы как shell-скрипты.
Ранние оболочки
Thompson shell — первая оригинальная командная оболочка Unix, стандартная для UNIX-версий AT&T с 1971 по 1979 годы. Современный синтаксис перенаправления потоков ввода/вывода был впервые реализован здесь. Концепция pipe реализована начиная с 1973 года. Thompson shell не являлась языком программирования. Управление логикой достигалось через внешние команды if и goto. В 1979 году в качестве стандартной заменена на Bourne shell.
Современные реализации исторической UNIX V6 shell для Unix-подобных систем — osh и etsh.
Главный предок большинства современных оболочек — Bourne shell (sh), созданная Стивеном Р. Борном в 1977–1978 годах и включённая в Unix V7. В большинстве коммерческих Unix-версий по-прежнему присутствует поздняя версия Bourne shell, хотя роль системной оболочки (/bin/sh) часто занимает другая shell. Уже в 7-й версии оболочка имела средства перенаправления, конвейеры, фоновые процессы и блочные конструкции. За редактирование командной строки отвечал терминальный драйвер: стирание всей строки (CTRL-U), последнего символа (DEL).
Со временем оригинальная версия расширялась и модифицировалась, обозначение обычно связывается с версией AT&T Unix, с которой распространялась (V7, System III, System V Release 1 — SVR1, SVR2, -3, -4, -4.2).
Синтаксис Bourne shell лежит в основе большинства современных Unix-оболочек — скрипты зачастую совместимы без изменений. Эта shell стала стандартом де-факто для Unix-скриптинга. По причине необходимости обратной совместимости всегда доступна совместимая с Bourne оболочка как /bin/sh.
Благодаря открытию исходного кода OpenSolaris/SVR4-версии Bourne shell компанией Sun и переработке управления памятью (с sbrk(2) на malloc(3)) Йоргом Шиллингом, эта shell теперь доступна практически для всех платформ. Производная Bourne shell («POSIX shell») по умолчанию используется в FreeBSD[2].
Несмотря на строгость функций Bourne shell, в сочетании со стандартными Unix-командами она покрывает все задачи командного интерпретатора. Синтаксис может показаться своеобразным. Пример:
#!/bin/sh
tageszeit=`date +%H`
if [ $tageszeit -lt 12 ]; then
echo "Guten Morgen."
else
echo "Guten Tag."
fi
В первой версии Bourne shell заложен механизм расширенных проверок прямо в командной конструкции (например, с помощью case). Она умела выполнять только булевы проверки; прочие условия требовали вызова внешних программ. В современных Bourne shell и их свободных преемниках команда test реализована встроенно и, как все внутренние, используется при наличии вместо внешних утилит. В примере вызывается встроенная [, для которой требуется финальное ], по сути это альтернативная запись test. Аргументы: текущий час $tageszeit, -lt (less than — меньше), 12. Возврат 0 (true) даёт выполнение блока then, возврат 1 (false) — выполнение else. Каждая ветка завершается fi (инверсия от if), заканчивающей условную конструкцию[3].[4]
Билл Джой (Bill Joy) разработал в Беркли для второй дистрибуции BSD (2BSD, 1979) оболочку, ориентированную на синтаксис языка C: C shell (csh). Здесь впервые реализованы редактирование командной строки (неинтерактивным способом), повтор (и правка) предыдущих команд и управление заданиями: через CTRL-Z команда приостанавливается, а внутренними командами fg (foreground) и bg (background) возобновляется.
C shell ввела многие популярные возможности, позже появившиеся в bash: псевдонимы (aliase), history. В наши дни C shell почти не используется — её вытеснили tcsh, ksh (Korn shell), bash (Bourne again shell), zsh. Существует нативная реализация C shell для Windows NT и старых версий OS/2 — Hamilton C shell.
Скриптовые возможности C shell ограничены: например, невозможно раздельно перенаправлять стандартный вывод и вывод ошибок. Пользователь, применяющий C shell в интерактивной работе, может начать скрипт с #!/bin/sh, чтобы обеспечить выполнение стандартной Bourne-совместимой или POSIX-совместимой оболочки — это возможно для любой shell.
Дальнейшее развитие
На каждом Unix-системе присутствует совместимая с Bourne оболочка /bin/sh. Доступность прочих оболочек зависит от варианта Unix; C shell часто встречается как /bin/csh. Благодаря различиям синтаксиса различают семейства оболочек — Bourne и C shell. Почти все современные оболочки реализованы на C, что облегчает портирование и добавление новых оболочек, включая и сторонние ОС.
Job control shell — Bourne-совместимая оболочка (конкретно, версия SVR4), дополненная возможностями управления заданиями, впервые появившимися в C shell. Часто это то же самое приложение, включающие дополнительные команды (bg, fg, jobs, kill, stop, suspend, wait) при запуске под именем jsh.
Дэвид Корн (David Korn) для Unix System V от AT&T разработал Korn shell (ksh). Она опирается на Bourne shell и внедряет новшества C shell: управление заданиями, расширенное редактирование командной строки. Существует версия 1988 года (ksh88) и более новая, 1993 года (ksh93). Korn shell 1988 года легла в основу POSIX-стандарта, но дополнительные конструкции (select, function, [[) над Bourne shell официально не регламентированы[5]. Korn shell долгое время была коммерческой, но с 1 марта 2000 года исходники ksh93 стали доступны. Многие проприетарные Unix-системы используют ksh как стандартную /bin/sh.
dtksh (Desktop Korn Shell) — версия Korn shell с расширениями для программирования пользовательских интерфейсов под X11/Motif.
Public domain Korn shell (pdksh) — свободная, частично совместимая реализация AT&T Korn shell. В ней реализовано много функций ksh88 и некоторые ksh93. Проект OpenBSD использует производную от pdksh как стандартную /bin/sh.
MirBSD Korn Shell (mksh) основана на pdksh из OpenBSD (oksh), но включает исправления и внешние функции.
Bourne Again Shell (bash)[6] входит в состав проекта GNU. Её название — игра слов и подчёркивает как преемственность Bourne shell, так и «рождение заново». В роли разработчиков выступили Brian Fox и Chet Ramey в конце 1980-х.
Bash в целом совместима с Bourne shell (sh), но заметно расширена. Она реализует многие черты Korn shell, понимает часть синтаксиса C shell: функцию истории команд, стек каталогов, переменную $RANDOM, POSIX-форму подстановки команд $(…), а также содержит ряд собственных расширений.
Bash (/bin/bash) — стандартная оболочка в большинстве Linux, а также некоторых версий macOS; портирована практически на все Unix-системы.
Для Windows доступны различные порты Bash:
- Cygwin
- MSYS (Minimal SYStem), компонент MinGW
- Microsoft Windows Services for UNIX
- Windows Subsystem for Linux
TENEX C shell (tcsh) — расширение C shell, написанное Христосом Зуласом: улучшено редактирование командной строки, реализованы автодополнение имён файлов, редактирование прямо в командной строке и др. Совместима с C shell.
Буква «t» в названии tcsh отсылает к TENEX — операционной системе, вдохновившей автора. tcsh заменила csh на многих Linux, BSD и старых версиях macOS.
Z shell (zsh) — оболочка с широким набором функций, близкая к Korn shell и содержащая возможности Bash, TENEX C shell, а также собственные разработки. Известна как одна из самых мощных Unix-оболочек; может применяться как логин-оболочка, интерактивная среда и интерпретатор скриптов.
Z shell реализует всё лучшее от bash, csh и tcsh.
Среди её возможностей:
- программируемое автодополнение;
- использование истории одновременных zsh-сеансов;
- проверка орфографии;
- почти полная совместимость с Bash, Korn shell и TENEX C shell;
- расширяемый prompt;
- расширенное глоббирование.
Z shell разработана Полом Фалстадом и выпущена в 1990 году в Usenet. Название — от логина zsh одного из его коллег.
Оболочка распространяется под BSD-лицензией, поэтому в macOS Catalina 10.15 Bash был заменён на zsh по умолчанию.
Almquist shell (ash), написанная Кеннетом Олмквистом, — переосмысленная Bourne shell (SVR4) для BSD-systems, когда Bourne shell стала недоступна без лицензии. Позднее ash была адаптирована под стандарт POSIX, её активно применяют для скриптинга, в том числе в FreeBSD и NetBSD. Благодаря невысоким требованиям к памяти и ресурсам используется как стандартная shell во встраиваемых системах Linux; интегрирована в BusyBox.
Debian Almquist shell, POSIX-совместимая Bourne-оболочка, является прямым потомком ash. Портирована в 1997 году Хербертом Сюй, в 2002 году получила название dash. В проекте Debian dash служит /bin/sh — она заметно быстрее, энергонезависимее и менее зависима, чем Bash; с 6.10 dash — стандартная оболочка в Ubuntu.
- Реализация Thompson shell — etsh, применявшаяся в Unix до появления Bourne shell.
- Unix-реализация командного интерпретатора Plan 9 — rc (run command), отличается более чётким синтаксисом, чем Bourne shell. Существуют производные: es (extensible shell) — легко расширяемая, с элементами функционального программирования.
- scsh (Scheme shell, автор Olin Shivers) — shell, где основной упор сделан на программирование через полноценный язык Scheme.
- esh (easy shell, Иван Ткачёв) — синтаксически ориентирована на Lisp.
- Наибольшую интерактивную дружественность реализует fish — friendly interactive shell.
- Heirloom Bourne Shell — порт OpenSolaris Bourne shell для Linux, Solaris, FreeBSD и NetBSD.
- nash (not a shell), разработанная в Red Hat для интерпретации образов «linuxrc» — не позиционирует себя как настоящая shell; применяется в mkinitrd в Red Hat, Mandriva[7].
- sash (Stand-alone shell) — shell, в которой большинство внешних команд встроены внутри, чтобы обеспечить контроль даже при отсутствии ключевых утилит.
- psh, psh2 — реализуют интерпретацию Perl-команд, позволяют, например, удобно работать с конвейерами[8].
- IPython реализует интерактивную shell с языком Python как основной[9].
Совместимость и переносимость
В зависимости от родословной оболочки скрипты под неё могут быть не полностью совместимы с другими оболочками. Например, скрипты Bourne shell нельзя напрямую запускать под C shell, но они, вероятно, заработают с Korn shell или job-control shell. Кроме того, поведение одной и той же оболочки зависит от варианта реализации и версии Unix, что влечёт различия в возможностях и наличие багов. Далее, shell-скрипты активно используют обычные Unix-команды, а их особенности отличаются между Unix-реализациями, что делает поведение скриптов при переносе на другие системы непредсказуемым.
Типичная стратегия при написании переносимых shell-скриптов — использовать только минимальный общий функционал, обычно в Bourne shell, намеренно отказываясь от удобных расширений и даже от новых, определённых в POSIX элементов, чтобы обеспечить максимальную переносимость.
Примечания
Литература
- Helmut Herold: Linux-Unix-Shells, Bourne-Shell, Korn-Shell, C-Shell, bash, tcsh. Addison-Wesley, München, 2003. ISBN 3-8273-1511-5.
- Alexander Mayer: Shell-Skripte in Unix. C&L – Computer & Literatur-Verlag, Böblingen, 2005. ISBN 3-936546-23-1.
- Morris I. Bolsky, David G. Korn: The New Korn Shell Command and Programming Language. 2-е издание. Prentice Hall, Upper Saddle River, 1995. ISBN 0-13-182700-6.
- Arnold Robbins, Bill Rosenblatt: Learning the Korn Shell, 2nd Edition. O’Reilly, Beijing, 2002. ISBN 0-596-00195-9.
- Paul Dubois: Using tcsh and csh. O’Reilly, Beijing, 1995. ISBN 1-56592-132-1.
- Patrick Ditchen: Shell-Skript Programmierung. 2-е изд. mitp, Heidelberg, 2006. ISBN 3-8266-1623-5.
- Ellie Quigley: UNIX Shells by Example, 4th Edition. Prentice Hall PTR, Upper Saddle River, 2005. ISBN 0-13-147572-X.
- O. Kiddle, J. Peek, P. Stephenson: From Bash to Z Shell. Apress, New York, 2004. ISBN 1-59059-376-6.
- Юрген Вольф (Jürgen Wolf): Shell-Programmierung – Einführung, Praxis, Referenz. Galileo Computing, Бонн, 2005. ISBN 3-89842-683-1.
- Sven Guckes, Julius Plenz: Zsh – Die magische Shell. Open Source Press, Мюнхен, 2008. ISBN 3-937514-59-7.
Ссылки
- The Unix Shell (англ.). swcarpentry.github.io. Дата обращения: 8 февраля 2024.


