61
Таким образом, окружение каждой команды формируется из всех унаследованных языком shell:
•пар (имя, значение),
•минус пары, удаленные командой unset,
•плюс все модифицированные и измененные пары, указанные в команде export.
Окружение простой команды может быть модифицировано, если указать перед командой одно или несколько присваиваний переменным. Так, строки
TERM=vt100 команда
и
(export TERM; TERM=vt100; команда)
являются эквивалентными, по крайней мере с точки зрения окружения команды.
Если установлен флаг -k, то все переменные, получившие значение в командой строке, помещаются в окружение команды, даже если они записаны после команды. В следующем примере, показанном на рисунке 3.2, приведена работа команды echo, предназначенной для вывода строк на консоль:
Рисунок 3.2 — Использование ключа -k в языке shell
Как было показано ранее, первое слово в строке shell воспринимает как команду, а остальные слова — как аргументы команды.
Пример, приведенный на рисунке 3.2, показывает, что это не всегда так:
•чтобы, в явном виде, разделить команды в строке, следует использовать разделитель — точка с запятой.
•в случае, когда команда не помещается в одну строку, для продолжения ее на другой строке, используется символ — обратный слэш.
•когда shell запускается посредством системного вызова exec*(...) и первым символом нулевого аргумента является -, то сначала читаются и выполняю-
62
тся команды из файлов /etc/profile и $HOME/.profile .
Все команды shell, условно, разделяются на две группы:
•встроенные команды — команды, которые интерпретатор выполняет самостоятельно;
•внешние команды — это программы и утилиты, которые shell ищет в
файловой системе и, после проверки прав доступа, пытается запустить, используя системные вызовы fork(...) и exec(...).
Кроме того, следует учесть что:
•под пробелом, в дальнейшем, понимается не только собственно пробел, но также и символ табуляции;
•имя - это последовательность букв, цифр, символов подчеркивания, начинающаяся с буквы или подчеркивания;
•параметр - это имя, цифра или любой из символов *, @, #, ?, -, $, !.
Перейдем к рассмотрению опций и аргументов. В общем случае, синтаксис запуска интерпретатора shell имеет вид:
sh [-a] [-c цепочка_символов][-e][-f][-h][-i][-k][-n][-r][-s][-t][-u][-v]
[-x] [аргумент ...]
где - квадратные скобки обозначают необязательные конструкции.
Перечисленные флаги (опции) интерпретируются shell при его запуске:
если не указаны опции -s или -c, то первый аргумент рассматривается как имя файла, содержащего команды;
остальные аргументы передаются этому командному файлу как позиционные параметры.
-c цепочка_символов
Команды берутся из цепочки_символов.
-s
Если аргументов больше нет, то команды читаются со стандартного ввода. Все оставшиеся аргументы рассматриваются как позиционные параметры.
Вывод сообщений самого shell, кроме специальных команд, направляется в файл с дескриптором 2 (стандартный протокол).
-i
если ввод и вывод shell ассоциированы с терминалом, shell выполняется в интерактивном режиме.
В этом случае сигнал завершения (0) игнорируется (то есть команда kill 0 не приведет к завершению работы
63
интерактив-ного shell'а).
Сигнал прерывания (2) перехватывается и игнорируется, поэ-тому выполнение системной функции wait (2) может быть прервано.
В любом случае, сигнал выхода (3) игнорируется.
-r
shell запускается как ограниченный [см. rsh(1)].
Замечание
Описание остальных флагов и аргументов приведено в описании команды set.
Все переменные shell, включая рассмотренные выше переменные среды, называются параметрами:
•различаются два типа параметров: позиционные и ключевые;
•знак $ используется для подстановки значений параметра.
Позиционные параметры обозначаются цифрой или одним из символов: *, @, #, ?, -, $, !.
Значения цифровых позиционных параметров устанавливаются при вызове shellфункций или командой set:
0 — параметр 0 — имя вызываемой функции;
1 — параметр 1 — аргумент 1;
2 — параметр 2 — аргумент 2 и далее.
Значения следующих параметров shell устанавливает автоматически:
* или @ содержат все позиционные параметры, начиная с 1, разделенные пробелами;
# количество позиционных параметров (десятичное);
- флаги, указанные при запуске shell или установленные командой set;
? десятичное значение, возвращенное предыдущей командой;
$ идентификатор процесса, в рамках которого выполняется shell; ! идентификатор последнего асинхронно запущенного процесса.
Пример вывода позиционных параметров, часть из которых установлено автоматически, показан сценарием рисунка 3.3, а результат вывода - рисунком 3.4.
64
Рисунок 3.3 — Сценарий вывода позиционных параметров
Рисунок 3.4 — Результат вывода сценария
Ключевые параметры (переменные) обозначаются именами. Значения им присваиваются обычным способом:
имя=значение [имя=значение] ...
65
Различаются следующие виды подстановок параметров:
${параметр}
Подставляется значение параметра, если оно определено. Скобки используются, только если за параметром следует буква, цифра или знак подчеркивания, и их нужно отделить от имени параметра.
Вместо параметров * и @ подставляются все позиционные параметры, начиная с $1, разделенные пробелами.
${параметр:-слово}
Будем говорить, что параметр пуст, если его значение
не определено или является пустой цепочкой. При данном способе подстановки если параметр не пуст, подставляется его значение; в противном случае подставляется слово.
${параметр:=слово}
Если параметр пуст, ему присваивается слово; после этого подставляется значение параметра. Таким способом нельзя изменять значения позиционных параметров.
${параметр:?слово}
Если параметр не пуст, подставляется его значение; в противном случае в стандартный протокол выдается сообщение "параметр:слово" и выполнение shell'а завершается. Если слово опущено, то выдается сообщение "параметр:parameter null or not set".
${параметр:+слово}
Если параметр не пуст, подставляется слово; в противном случае не подставляется ничего.
Замечание
После проведения подстановок, полученная строка просматривается в поисках разделителей, которые берутся из системной переменной IFS, и расщепляется на аргументы.
Явные пустые аргументы сохраняются. Неявные пустые аргументы удаляются.