Брайан Керниган - UNIX — универсальная среда программирования
- Название:UNIX — универсальная среда программирования
- Автор:
- Жанр:
- Издательство:Финансы и статистика
- Год:1992
- Город:Москва
- ISBN:5-289-00253-4
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Брайан Керниган - UNIX — универсальная среда программирования краткое содержание
В книге американских авторов — разработчиков операционной системы UNIX — блестяще решена проблема автоматизации деятельности программиста, системной поддержки его творчества, выходящей за рамки языков программирования. Профессионалам открыт богатый "встроенный" арсенал системы UNIX. Многочисленными примерами иллюстрировано использование языка управления заданиями shell.
Для программистов-пользователей операционной системы UNIX.
UNIX — универсальная среда программирования - читать онлайн бесплатно ознакомительный отрывок
Интервал:
Закладка:
Каждая команда вырабатывает код завершения — значение, передаваемое интерпретатору и показывающее, что произошло. Это небольшое целое число, которое устанавливается по соглашению. Так, нуль может означать "истину" (команда успешно завершена), а ненулевое значение трактуется как "ложь" (выполнение команды было неудачным). Обратите внимание на то, что выбранные здесь значения противоположны значениям истины и лжи в языке Си.
Поскольку ложь может представлять множество различных значений, причина неудачи обозначается кодом завершения по лжи. Например, команда grep возвращает 0, если произошло сопоставление, 1 — если сопоставления не было, и 2 — в случае ошибки в шаблоне или именах файлов. Каждая программа возвращает код завершения, хотя обычно нас не интересует его значение. Команда testнеординарна: ее единственное назначение состоит в передаче кода завершения. Она ничего не выводит и не изменяет файлы.
Интерпретатор хранит код завершения последней программы в переменной $?:
$ cmp /usr/you/.profile /usr/you/.profile
$Выдачи нет, файлы совпадают
$ echo $?
00 означает успех, файлы идентичны
$ cmp /usr/you/.profile /usr/mary/.profile
/usr/you/.profile /usr/mary/.profile differ: char 6, line 3
$ echo $?
1He нуль означает, что файлы различны
$
У некоторых команд, таких, как cmpи grep, есть флаг -s, который заставляет их завершить выполнение с определенным кодом, но подавляет вывод. Оператор ifязыка shellзапускает команды в зависимости от кода завершения некоторой команды, а именно:
if команда
then
команды, если условие верно
else
команды, если условие ложно
fi
Местоположение символов перевода строк очень важно: fi, thenи elseраспознаются только после символа перевода строки или точки с запятой.
Оператор ifвсегда запускает команду (условие), тогда как в операторе caseсопоставление с шаблоном производится самим интерпретатором. В некоторых версиях UNIX, включая System V, testявляется встроенной командой интерпретатора, поэтому ifи testбудут выполняться так же быстро, как и case. Если test— не встроенная команда, то операторы caseболее эффективны, чем операторы if, и следует использовать именно их для поиска шаблонов;
$ case "$1" in
hello) command
esac
выполняется быстрее, чем
if test "$1"==helloМедленнее, если test не встроенная
then
command
fi
Это одна из причин, по которой в языке shellиногда для проверки условий применяются операторы case, хотя в большинстве языков программирования использовались бы операторы if. С другой стороны, с помощью оператора caseнепросто определить, имеется ли право доступа к файлу на чтение; здесь предпочтение следует отдать команде testи оператору if.
Итак, теперь мы готовы воспользоваться первой версией команды which, которая выведет сообщение о том, какой файл соответствует команде:
$ cat which
# which cmd: which cmd in PATH is executed, version 1
case $# in
0) echo 'Usage: which command' 1>&2; exit 2
esac
for i in `echo $PATH | sed 's/^:/.:/
s/::/:.:/g
s/:$/:./
s/:/ /g'`
do
if test -f $i/$1 # use test -x if you can
then
echo $i/$1
exit 0 # found it
fi
done
exit 1 # not found
$
Проверим ее:
$ cx whichСделаем ее выполняемой
$ which which
./which
$ which ed
/bin/ed
$ mv which /usr/you/bin
$ which which
/usr/you/bin/which
$
Первый оператор caseосуществляет контроль ошибки. Обратите внимание на переключение 1>&2в команде echo, которое выполняется для того, чтобы сообщение об ошибке не пропало в программном канале. Встроенная команда интерпретатора exitможет использоваться для передачи кода завершения. В нашем примере exit 2передает код завершения в ситуации, когда команда не выполняется, exit 1— в ситуации, когда файл не удалось найти, и exit 0— в ситуации, когда файл найден. Если нет явного оператора exit, кодом завершения командного файла является код завершения последней выполняемой команды.
Что произойдет, если в вашем текущем каталоге есть программа под именем test? (Мы предполагаем, что testне является встроенной командой.)
$ echo 'echo hello' >testСделаем поддельную команду test
$ cx test Сделаем ее выполняемой
$ which which Попробуем which теперь
hello Неудача!
./which
$
Вывод: требуется больший контроль. Можно запустить команду which(если нет команды testв текущем каталоге), чтобы определить полное имя для testи задать его явно. Но это не лучшее решение, поскольку команда testможет присутствовать в различных каталогах в разных версиях системы, а команда whichзависит от sedи echo, так что необходимо указать и их полные имена. Можно поступить проще — установить значение PATHв командном файле так, чтобы поиск команд осуществлялся только в /binи /usr/bin. Конечно, это возможно только в команде which, причем прежнее значение PATHследует сохранить для определения последовательности каталогов при поиске.
$ cat which
# which cmd: which cmd in PATH is executed, final version
opath=$PATH
PATH=/bin:/usr/bin
case $# in
0) echo 'Usage: which command' 1>&2; exit 2
esac
for i in `echo $opath | sed 's/^:/.:/
s/::/:.:/g
s/ :$/:./
s/:/ /g'`
do
if test -f $i/$1 # this is /bin/test
then # or /usr/bin/test only
echo $i/$1
exit 0 # found it
fi
done
exit 1 # not found
$
Теперь команда whichвыполняется даже в том случае, если есть "поддельная" команда test( sedили echo) среди каталогов, входящих в PATH.
$ ls -l test
-rwxrwxrwx 1 you 11 Oct 1 06:55 testВсе еще здесь
$ which which
/usr/you/bin/which
$ which test
./test
$ rm test
$ which test
/bin/test
$
В языке shellимеются две операции, объединяющие команды ||и &&, использование которых часто более компактно и удобно, чем оператора if. Например, операция ||может заменить некоторые операторы if:
test -f имя_файла || echo имя_файла не существует
эквивалентно
if test ! -f имя_файла! обращает условие
then
echo имя файла не существует
fi
Операция ||, несмотря на свой вид, не имеет ничего общего с конвейерами — это обычная операция, означающая ИЛИ. Выполняется команда слева от ||. Если ее код завершения 0 (успех), справа от ||команда игнорируется. Если команда слева возвращает другое значение (неудача), выполняется команда справа, и значение всего выражения есть код завершения правой команды. Иными словами, ||представляет собой обычную операцию ИЛИ, которая не выполняет свою правую часть, если левая часть завершилась успешно. Соответственно &&есть обычная операция И, выполняющая свою правую часть, только если левая часть завершилась успешно.
Интервал:
Закладка: