|
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
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'ом поддерживаются следующие сигналы:
Сигналы SIGINT и SIGQUIT игнорируются, если команда была запущена асинхронно. Иначе сигналы обрабатываются так же, как в процессе-предке, за исключением сигнала SIGSEGV (см. также Специальные команды. Trap). 4.5. ЗамечанияПри выполнении команд запоминается их местонахождение. Поэтому при создании команды с тем же именем, но находящейся в другой директории, все равно будет выполняться старая команда (если вызов происходит по короткому имени). Для исправления ситуации воспользуйтесь командой hash с ключом -r (см. Специальные команды). Если вы переименовали текущую или вышележащую директорию, то команда pwd может давать неверную информацию. Для исправления ситуации воспользуйтесь командой cd с полным именем директории. 5. Дополнительные сведения5.1. Команда testКоманда test применяется для проверки условия. Формат вызова:
test <выражение>
или
[ <выражение> ]
Команда test вычисляет <выражение> и, если его значение - истина, возвращает код завершения 0 (true); иначе - ненулевое значение (false). Ненулевой код завершения возвращается и если опущены аргументы. <Выражение> может состоять из следующих примитивов:
5.2. Команда exprКоманда expr применяется для вычисления выражений. Результат выводится на стандартный вывод. Операнды выражения должны быть разделены пробелами. Метасимволы должны быть экранированы. Надо заметить, что 0 возвращается в качестве числа, а не для индикации пустой строки. Строки, содержащие пробелы или другие специальные символы, должны быть заключены в кавычки. Целые рассматриваются как 32-битные числа. Ниже приведен список операторов в порядке возрастания приоритета, операции с равным приоритетом заключены в фигурные скобки. Перед символами, которые должны быть экранированы, стоит \.
Регулярное выражение строится следующим образом:
Все остальные символы (и ^, если стоит не в квадратных скобках) обозначают самих себя. Для указания символов ., *,[ и ] надо экранировать их (т.е. писать \., \*, \[, \]). Примеры.1. a=`expr $a + 1`- увеличение на 1 переменной a 2. expr $a : '.*/\(.*\)' \| $a- выделяет из имени файла короткое имя (т.е. из /usr/util/ena выделяется ena). Внимание, одиночный символ / будет воспринят как знак операции деления. 3. expr $VAR : '.*'- получение количества символов переменной VAR. В качестве побочного эффекта expr возвращает следующие коды завершения:
Команда expr также выдает следующие сообщения об ошибках:
Замечание.Допустим, что мы хотим сравнить значение переменной a с каким-либо символом, имеющим для expr особый смысл, например, со знаком равенства. Пусть $a на самом деле является знаком равенства. Так как аргументы предварительно обрабатываются shell'ом, то команда
expr $a = '='
будет воспринята как
expr = = =
что синтаксически некорректно. В подобных случаях надо пользоваться таким приемом:
expr X$a = X=
т.е. добавлением некоторого символа к обеим строкам, что никак не влияет на результат сравнения, однако позволяет избежать синтаксической ошибки. 5.3. Команда enaКоманда ena позволяет получить части полного имени файла. Первый аргумент - флаг, второй - имя файла. Команда различает следующие флаги:
Ниже приводится текст программы 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
|
|
CITForum © 1997–2025