Командная оболочка 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 используют архитектуру системы: реализуют только базовые возможности, а расширяют их за счёт внешних команд — через развитые механизмы ввода/вывода и конвейеров. В 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

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]

C shell

Билл Джой (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

Job control shell — Bourne-совместимая оболочка (конкретно, версия SVR4), дополненная возможностями управления заданиями, впервые появившимися в C shell. Часто это то же самое приложение, включающие дополнительные команды (bg, fg, jobs, kill, stop, suspend, wait) при запуске под именем jsh.

Korn shell

Дэвид Корн (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

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

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:

TENEX C shell

TENEX C shell (tcsh) — расширение C shell, написанное Христосом Зуласом: улучшено редактирование командной строки, реализованы автодополнение имён файлов, редактирование прямо в командной строке и др. Совместима с C shell.

Буква «t» в названии tcsh отсылает к TENEX — операционной системе, вдохновившей автора. tcsh заменила csh на многих Linux, BSD и старых версиях macOS.

Z shell

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

Almquist shell (ash), написанная Кеннетом Олмквистом, — переосмысленная Bourne shell (SVR4) для BSD-systems, когда Bourne shell стала недоступна без лицензии. Позднее ash была адаптирована под стандарт POSIX, её активно применяют для скриптинга, в том числе в FreeBSD и NetBSD. Благодаря невысоким требованиям к памяти и ресурсам используется как стандартная shell во встраиваемых системах Linux; интегрирована в BusyBox.

Debian Almquist shell

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 9rc (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.