Структура командной строки
Командные строки рассматриваются по одной и имеют определенную структуру. Чтобы понять ее, рассмотрим ряд синтаксических определений:
<пробел> ::=
<символ пробела> | <символ табуляции>
<имя> ::=
<буква или подчеркивание> {<допустимый символ имени>}
<буква или подчеркивание> ::=
<буква> | _
<допустимый символ имени> ::=
<буква> | <цифра> | _
<параметр> ::=
<имя> | <цифра> | * | @ | # | ? | - | $ | !
<слово> ::=
<не пробел> {<не пробел>}
<простая команда> ::=
<слово> {<пробел> <слово>}
Итак, простая команда - это последовательность слов через пробел. Нажатие клавиши Enter при вводе команды или перевод строки при обработке сценария являются для командного интерпретатора признаком завершения команды. Она обрабатывается и выполняется.
Значением простой команды является ее статус выхода (см. ) в случае нормального завершения или (восьмеричное) 200+статус при ненормальном завершении.
Пример простой команды:
$ who oracle pts000 Aug 20 10:08 root console Aug 20 09:03 intdbi pts004 Aug 20 12:45 $
Из простых команд строятся более сложные конструкции: конвейеры и списки.
<конвейер> ::=
<команда> {| <команда>}
<список> ::=
<конвейер> {<разделитель> <конвейер>} [<терминатор команды>]
<разделитель> ::=
&& | | <терминатор команды>
<терминатор команды> ::=
; | &
Конвейер - это последовательность одной или более команд, разделенных |. Стандартный выходной поток каждой команды, кроме последней, соединяется при помощи программного канала со стандартным входным потоком следующей команды. Каждая команда выполняется как отдельный процесс; интерпретатор ожидает окончания последней команды. Статусом выхода конвейера является статус выхода его последней команды. Вот пример простого конвейера:
$ ls | tee save | wc 15 15 100 $
Список - это последовательность одного или более конвейеров, разделенных ;, &, && или и, возможно, заканчивающаяся ; или &. Из этих четырех символов, ; и & имеют равный приоритет, который ниже, чем у && и (эти символы тоже имеют равный приоритет). Точка с запятой (;) вызывает последовательное выполнение предшествующего конвейера (т.е. командный интерпретатор ожидает окончания конвейера перед выполнением любых команд, следующих за точкой с запятой). Амперсанд (&) вызывает асинхронное выполнение предшествующего конвейера (т.е. командный интерпретатор не ожидает окончания работы конвейера). Символ && () ведет к тому, что следующий за ним список выполняется только в том случае, когда предыдущий конвейер вернул нулевой (ненулевой) статус выхода. В список может входить произвольное количество переводов строк и точек с запятой, разделяющих команды.
Теперь можно дать общее определение команды:
<команда> ::=
<простая команда> |
<оператор управления> |
<определение функции> |
<список> | (<список>) | { <список>; }
Список в круглых скобках выполняется в порожденном командном интерпретаторе. Круглые скобки обычно используют для группировки команд.
Список в фигурных скобках выполняется в текущем командном интерпретаторе, без порождения дополнительного процесса, и замещает образ командного интерпретатора (это аналог системного вызова exec).
Операторы управления и синтаксис определения функций рассматривается далее.
Рассмотрим пример сложной команды:
bash$ (sleep 5; date) & date [1] 1148 Wed Aug 20 15:00:11 ???? 1997 bash$ Wed Aug 20 15:00:16 ???? 1997
Фоновый процесс начинается, но сразу "засыпает"; тем временем вторая команда date выдает текущее время, а интерпретатор - приглашение для ввода новой команды. Через пять (примерно, зависит от загрузки системы и т.п.) секунд прекращается выполнение команды sleep и первая команда date выдает новое время.