Интерпретатор командного языка shell. Выполнение shell-программ
4. Выполнение shell-программ
4.1. Запуск shell'а
Программа, интерпретирующая
shell-программы, находится в файле
/bin/sh. При запуске ее первый аргумент
является именем shell-программы,
остальные передаются как
позициональные параметры. Если
файл, содержащий shell-программу,
имеет право выполнения (x), то
достаточно указания лишь его имени.
Например, следующие две команды
операционной системы эквивалентны
(если файл ficofl обладает указанным
правом и на самом деле содержит
shell-программу):
sh ficofl -d . g*
и
ficofl -d . g*
4.2. Выполнение
При выполнении shell-программ
выполняются все подстановки. Если
имя команды совпадает с именем
специальной команды, то она
выполнается в рамках текущего
процесса. Так же выполняются и
определенные пользователем
функции. Если имя команды не
совпадает ни с именем специальной
команды, ни с именем функции, то
порождается новый процесс и
осуществляется попытка выполнить
указанную команду.
Переменная PATH определяет путь
поиска директории, содержащей
данную команду. По умолчанию это
::/bin:/usr/ bin:/util:/dss/rk
Директории поиска разделяются
двоеточиями; :: означает текущую
директорию. Если имя команды
содержит символ /, значение $PATH не
используется: имена, начинающиеся с
/ ищутся от корня, остальные - от
текущей директории. Положение
найденной команды запоминается
shellом и может быть опрошено
командой hash.
4.3. Окружение
Окружение - это набор пар
имя-значение, которые передаются
выполняемой программе. Shell
взаимодействует с окружением
несколькими способами. При запуске
shell создает переменную для каждой
указанной пары, придавая ей
соответствующее значение. Если вы
измените значение какой-либо из
этих переменных или создадите
новую переменную, то это не окажет
никакого влияния на окружение, если
не будет использована команда export
для связи переменной shell'а с
окружением (см. также set -a).
Переменная может быть удалена из
окружения командой unset (см.). Таким
образом, окружение каждой из
выполняемых shell'ом команд
формируется из всех неизмененных
пар имя-значение, первоначально
полученных shell'ом, минус пары,
удаленные командой unset, плюс все
модифицированные и измененные
пары, которые для этого должны быть
указаны в команде export.
Окружение простых команд может
быть сформировано указанием перед
ней одного или нескольких
присваиваний переменным. Так,
TERM=d460 <команда>
и
(export TERM; TERM=d460; <команда>)
эквивалентны. Переменные,
участвующие в таких присваиваниях,
назовем ключевыми параметрами.
Если установлен флаг -k (см. set), то
все ключевые параметры помещаются
в окружение команды, даже если они
записаны после команды.
4.4. Сигналы
UNIX'ом поддерживаются следующие
сигналы:
SIGHUP |
- 1 - |
отменить (hangup) |
SIGINT |
- 2 - |
прерывание (interrupt) |
SIGQUIT |
- 3 - |
нестандартный выход
(quit) |
SIGILL |
- 4 - |
неверная команда (illegal
instruction) |
SIGTRAP |
- 5 - |
ловушка (trace trap) |
SIGFPE |
- 8 - |
исключительная
ситуация при выполнении
операций с плавающей запятой
(floating-point exception) |
SIGKILL |
- 9 - |
уничтожение процесса
(kill) |
SIGBUS |
- 10 - |
ошибка шины (bus error) |
SIGSEGV |
- 11 - |
нарушение
сегментации (segmentation violation) |
SIGSYS |
- 12 - |
неверный системный
вызов (bad argument to system call) |
SIGPIPE |
- 13 - |
запись в канал без
чтения из него (write on a pipe with no one
to read it) |
SIGALRM |
- 14 - |
будильник (alarm clock) |
SIGTERM |
- 15 - |
программное
завершение процесса (software
termination signal) |
Сигналы SIGINT и SIGQUIT игнорируются,
если команда была запущена
асинхронно. Иначе сигналы
обрабатываются так же, как в
процессе-предке, за исключением
сигнала SIGSEGV (см. также Специальные
команды. Trap).
4.5. Замечания
При выполнении команд
запоминается их местонахождение.
Поэтому при создании команды с тем
же именем, но находящейся в другой
директории, все равно будет
выполняться старая команда (если
вызов происходит по короткому
имени). Для исправления ситуации
воспользуйтесь командой hash с
ключом -r (см. Специальные команды).
Если вы переименовали текущую или
вышележащую директорию, то команда
pwd может давать неверную
информацию. Для исправления
ситуации воспользуйтесь командой cd
с полным именем директории.
5. Дополнительные
сведения
5.1. Команда test
Команда test применяется для
проверки условия. Формат вызова:
test <выражение>
или
[ <выражение> ]
Команда test вычисляет
<выражение> и, если его значение -
истина, возвращает код завершения 0
(true); иначе - ненулевое значение (false).
Ненулевой код завершения
возвращается и если опущены
аргументы. <Выражение> может
состоять из следующих примитивов:
-r файл |
- истина, если файл
существует и доступен для
чтения |
-w файл |
- истина, если файл
существует и доступен для
записи |
-x файл |
- истина, если файл
существует и является
выполняемым |
-f файл |
- истина, если файл
существует и является обычным
файлом |
-d файл |
- истина, если файл
существует и является
директорией |
-c файл |
- истина, если файл
существует и является
специальным
символьно-ориентированным
файлом |
-b файл |
- истина, если файл
существует и является
специальным
блок-ориентированным файлом |
-p файл |
- истина, если файл
существует и является
именованным каналом (pipe) |
-s файл |
- истина, если файл
существует и имеет ненулевую
длину |
-t [ дескриптор файла ] |
- истина, если
открытый файл с указанным
дескриптором (по умолчанию 1)
существует и ассоциирован с
терминалом |
-z s1 |
- истина, если длина
строки s1 нулевая |
-n s1 |
- истина, если длина
строки s1 ненулевая |
s1 = s2 |
- истина, если строки s1
и s2 совпадают |
s1 != s2 |
- истина, если строки s1
и s2 не совпадают |
s1 |
- истина, если s1
непустая строка |
n1 -eq n2 |
- истина, если целые n1
и n2 алгебраически совпадают .
На месте -eq могут быть также -ne,
-gt, -ge, -lt, -le |
5.2. Команда expr
Команда expr применяется для
вычисления выражений. Результат
выводится на стандартный вывод.
Операнды выражения должны быть
разделены пробелами. Метасимволы
должны быть экранированы. Надо
заметить, что 0 возвращается в
качестве числа, а не для индикации
пустой строки. Строки, содержащие
пробелы или другие специальные
символы, должны быть заключены в
кавычки. Целые рассматриваются как
32-битные числа.
Ниже приведен список операторов в
порядке возрастания приоритета,
операции с равным приоритетом
заключены в фигурные скобки. Перед
символами, которые должны быть
экранированы, стоит .
<выр> | <выр> |
если первое <выр>
не пустое и не нулевое, то
возвращает его, иначе
возвращает второе <выр> |
<выр> & <выр> |
если оба <выр> не
пустые и не нулевые, то
возвращает первое <выр>,
иначе возвращает 0 |
<выр> { =, >, >=,
<, <=, != } <выр> |
возвращает результат
целочисленного сравнения если
оба <выр> - целые; иначе
возвращает результат
лексического сравнения |
<выр> { +, - } <выр> |
сложение и вычитание
целочисленных аргументов |
<выр> { *, /, % }
<выр> |
умножение, деление и
получение остатка от деления
целочисленных аргументов |
<выр> : <выр> |
оператор
сопоставления : сопоставляет
первый аргумент со вторым,
который должен быть регулярным
выражением. Обычно оператор
сравнения возвращает число
символов, удовлетворяющих
образцу (0 при неудачном
сравнении). Однако символы ( и )
могут применяться для
выделения части первого
аргумента. |
Регулярное выражение строится
следующим образом:
. |
- обозначает любой
символ |
* |
- обозначает
предыдущий символ, повторенный
несколько раз |
[] |
- обозначают любой
один из указанных между ними
символов; группа символов
может обозначаться с помощью
знака "-" (т.е. [0-9]
эквивалентно [0123456789]); если
после [ стоит ^, то это
эквивалентно любому символу,
кроме указанных в скобках и
<возврата_каретки>; для
указания ] в качестве образца,
надо поставить ее сразу за [
(т.е. []...]); . и * внутри квадратных
скобок обозначают самих себя |
Все остальные символы (и ^, если
стоит не в квадратных скобках)
обозначают самих себя. Для указания
символов ., *,[ и ] надо экранировать
их (т.е. писать ., *, [, ]).
Примеры.
1.
a=`expr $a + 1`
- увеличение на 1 переменной a
2.
expr $a : '.*/(.*)' | $a
- выделяет из имени файла короткое
имя (т.е. из /usr/util/ena выделяется ena).
Внимание, одиночный символ / будет
воспринят как знак операции
деления.
3.
expr $VAR : '.*'
- получение количества символов
переменной VAR.
В качестве побочного эффекта expr
возвращает следующие коды
завершения:
0 |
- если выражение не
нуль и не пустая строка |
1 |
- если выражение нуль
или пустая строка |
2 |
- для некорректных
выражений |
Команда expr также выдает следующие
сообщения об ошибках:
syntax error |
- для ошибок в
операторах или операндах |
non-numeric argument |
- для попыток
применения арифметических
операций к нечисловым строкам |
Замечание.
Допустим, что мы хотим сравнить
значение переменной a с каким-либо
символом, имеющим для expr особый
смысл, например, со знаком
равенства. Пусть $a на самом деле
является знаком равенства. Так как
аргументы предварительно
обрабатываются shell'ом, то команда
expr $a = '='
будет воспринята как
expr = = =
что синтаксически некорректно. В
подобных случаях надо пользоваться
таким приемом:
expr X$a = X=
т.е. добавлением некоторого
символа к обеим строкам, что никак
не влияет на результат сравнения,
однако позволяет избежать
синтаксической ошибки.
5.3. Команда ena
Команда ena позволяет получить
части полного имени файла. Первый
аргумент - флаг, второй - имя файла.
Команда различает следующие флаги:
-n |
- имя файла без
расширения |
-f |
- имя файла с
расширением |
-e |
- расширение |
-d |
- имя директории |
-p |
- если имя файла
начинается с . или .. , то эти
символы выделяются из имени |
Ниже приводится текст программы
ena, хранящийся в /util/ena.
# Get part of pathname
case $1 in
-n )
expr $2 : '.*/(.*)[.].*' | $2 : '(.*)[.].*' | $2
;;
-f )
expr $2 : '.*/(.*)' | $2
;;
-e )
expr $2 : '.*([.][^./]*)' | ' '
;;
-d )
expr $2 : '(.*)/.*' | $2
;;
-p )
expr $2 : '([.])/.*' | $2 : '([.][.])/.*' | ' '
;;
* )
echo "error: unknown part of pathname $1"
exit 2
;;
esac
Назад | Содержание
|