Опубликован: 15.06.2004 | Доступ: свободный | Студентов: 2557 / 712 | Оценка: 4.35 / 3.96 | Длительность: 27:47:00
ISBN: 978-5-9556-0011-6
Лекция 2:

Язык shell

Аннотация: Описывается синтаксис и семантика командного языка shell, способы вызова командного интерпретатора shell, приводятся примеры shell-процедур, анализируются правила формирования и средства разбора командных строк.
Ключевые слова: слово, shell, язык программирования, командный интерпретатор, мобильное программирование, конвейер, значение, переменная, шаблон имен файлов, командная строка, пользовательский интерфейс, пробел, имя, параметр, комментарий, простая команда, поле, перенаправление ввода/вывода, аргумент, код завершения, команда, управляющая конструкция, вывод, стандартный ввод, список, shell-процедура, программа, необязательная часть, повторение, POSIX, ПО, утилита, файл, информация, фильтр, канал, имя переменной, операции, интерпретатор, значение переменной, запись, язык shell, присваивание, стандартный протокол, интерпретация, сопоставление с образцом, шаблон, суффикс, префикс, опция, синхронно выполненная команда, идентификатор процесса, идентификатор, асинхронно запущенный процесс, окружение процесса, смена текущего каталога, домашний каталог пользователя, цепочка символов, разделитель полей, перевод строки, список поиска, пустой элемент, текущий каталог, интерактивный shell, поиск, экранный интерфейс, часовой пояс, текущее время, почтовое взаимодействие, подстановка результатов, место, вычисление выражения, константы, управляющие, цикл, цикла, условие продолжения цикла, оператор выбора, определение функции, функция, имя функции, тело функции, фигурные скобки, вызов функции, синтаксис, время выполнения, аргумент функции, истина, операция отрицания, логическое И, логическое ИЛИ, компонент, CASE, определение, имя файла, runlevel, тильда, входное имя, дескриптор, верхняя граница, номер дескриптора, нотация, дескриптор файла, перенаправление вывода, вставка, экранирование, подстановка, исключение, встроенная команда, специальная встроенная команда, смена программы процесса, обычная встроенная команда, конец файла, пользователь, единица, оператор присваивания, остаток, запуск, экспорт переменных в окружение, трассировка, set, синоним, инвертирование, терминал, имя программы, аргумент опции, операнд, имя опции, буквенно-цифровой символ, индекс, цепочка имен опций, диагностическое сообщение, указатель

Основные понятия языка shell

В дальнейшем изложении слово shell будет употребляться в двух смыслах - как имя языка программирования и как название командного интерпретатора.

Для нас shell важен прежде всего как мощный язык мобильного программирования. Предваряя дальнейшее изложение, отметим имеющиеся в нем возможности комбинирования команд с помощью конвейеров, подстановки значений переменных и результатов выполнения команд, генерации имен файлов по шаблонам.

Свойства shell как интерактивного командного интерпретатора, непосредственно взаимодействующего с пользователем, хранение и использование истории сеанса, возможности редактирования командной строки и т.п., на ваш взгляд, менее актуальны, поскольку современный пользовательский интерфейс строится на иной основе.

Выделим основные понятия языка shell на лексическом уровне.

Под пробелом в дальнейшем понимается не только собственно пробел, но также и символ табуляции.

Слово - это лексема, отличная от знака операции.

Имя - последовательность букв, цифр, символов подчеркивания, начинающаяся с буквы или подчеркивания.

Параметр - имя, цифра или любой из символов *, @, #, ?, -, $, !.

Комментарий - лексема, начинающаяся с символа #, а также вся последующая часть строки.

На синтаксическом уровне различаются несколько видов команд.

Простая команда - последовательность полей с разделителями (обычно пробелами) между ними. Первое поле определяет имя команды, которая будет выполняться; оставшиеся поля, за исключением присваиваемых параметрам и перенаправления ввода/вывода (см. далее), передаются команде в качестве аргументов. Имя команды передается как аргумент 0.

Значение простой команды - ее код завершения.

Команда - это либо простая команда, либо одна из управляющих конструкций (см. далее). Кодом завершения команды является код завершения последней выполненной простой команды.

Конвейер - последовательность команд, разделенных знаком | . Стандартный вывод всех команд, кроме последней, направляется на стандартный ввод следующей команды конвейера. Каждая команда выполняется как самостоятельный процесс; shell ожидает завершения последней команды, код завершения которой становится кодом завершения конвейера. Формально будем считать простую команду частным случаем конвейера.

Список - последовательность из одного или нескольких разделенных символами ;, &, && или || конвейеров, она может заканчиваться символами ; или & . Из четырех указанных операций ; и & имеют равные приоритеты, меньшие, чем у && и ||. Приоритеты последних также равны между собой. Символ ; означает, что конвейеры будут выполняться последовательно, а & - параллельно (т. е. shell не ожидает завершения конвейера ). Операция && ( || ) означает, что список, следующий за ней, будет выполняться лишь в том случае, если код завершения предыдущего конвейера нулевой (ненулевой). В списке в качестве разделителя конвейеров вместо символа ; можно использовать символ перевода строки.

Командная строка - строка текста на языке shell.

Shell-процедура - файл, содержащий программу на языке shell.

Для выполнения (почти) каждой простой команды shell порождает отдельный процесс, в рамках которого выполняется программа, хранящаяся в файле, заданном именем команды. Программа может быть выполнимой, т. е. содержать машинные инструкции, или представлять собой shell-процедуру - содержать текст на языке shell.

Далее при описании синтаксиса конструкций языка shell и способа вызова служебных программ будут использоваться следующие соглашения:

  • в квадратные скобки заключаются необязательные части конструкций;
  • многоточие означает повторение предыдущей части конструкции произвольное число раз.

Конвейеры и примеры их использования

Конвейер - одна из самых красивых конструкций ОС Unix, вошедшая, разумеется, и в стандарт POSIX. Идея его проста, но на редкость продуктивна. С помощью конвейеров удается комбинировать возможности, предоставляемые разными командами, получая по существу новое качество.

Например, утилита ls не подсчитывает число файлов в каталоге, а лишь выдает информацию о них. С другой стороны, служебная программа wc способна подсчитать число строк в файле, но не имеет отношения к распечатке содержимого каталогов. Если же построить конвейер из двух упомянутых команд, количество файлов в каталоге легко вычисляется. Например, результатом работы конвейера (см. листинг 2.1) на нашей установке ОС Linux будет число 92 (утилита wc, вызванная без аргументов, обрабатывает файл стандартного ввода, который в данном случае является результатом работы команды ls ). Значит, в каталоге /bin 91 файл, если считать и элементы, соответствующие текущему и вышележащему каталогам (первая строка выдачи ls содержит суммарное число блоков, занятых файлами каталога).

ls -al /bin | wc -l
Листинг 2.1. Пример конвейера.

Еще один пример. Пусть необходима информация о файлах текущего каталога, модифицированных в октябре. К цели ведет конвейер, показанный в листинге 2.2:

ls -al | grep "Oct "
Листинг 2.2. Еще один пример конвейера.

Служебная программа grep играет здесь роль фильтра, который пропускает для вывода только часть строк, выдаваемых ls.

Можно выстроить и трехступенчатый конвейер, если требуется подсчитать число файлов, модифицированных в октябре (см. листинг 2.3):

ls -al | grep "Oct " | wc -l
Листинг 2.3. Пример трехступенчатого конвейера.

Здесь утилиту grep с еще большим правом можно назвать фильтром.

Приведем еще один пример конвейера, полезного, когда нужна подробная информация о большом каталоге (см. листинг 2.4):

ls -Rl /dev | more
Листинг 2.4. Конвейер для поэкранного просмотра результатов.

Связующее звено между последовательными компонентами конвейера называется каналом . Иными словами, для интерпретации конвейера shell создает временный файл типа "канал", с одного конца в него заносят данные, а с другого - читают. С помощью служебной программы tee можно организовать ответвление канала, т. е. помещать информацию не только на стандартный вывод, но и в указанные файлы:

tee файл ...

Например, если нужно не только подсчитать число файлов из текущего каталога, модифицированных в октябре, но и поместить информацию о них в файл для последующего анализа, следует построить четырехступенчатый конвейер (см. листинг 2.5):

ls -al | grep "Oct" | tee /tmp/tmpinf | wc -l
Листинг 2.5. Четырехступенчатый конвейер.

В результате его выполнения на экране появится сообщение о количестве нужных файлов, а в файле /tmp/tmpinf - информация о них.

Антон Коновалов
Антон Коновалов

В настоящее время актуальный стандарт - это POSIX 2008 и его дополнение POSIX 1003.13
Планируется ли актуализация материалов данного очень полезного курса?