Шрифт:
$ 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 имя_файла
! обращает условие – f имя_файла
then
echo имя файла не существует
fi
Операция
||
, несмотря на свой вид, не имеет ничего общего с конвейерами — это обычная операция, означающая ИЛИ. Выполняется команда слева от ||
. Если ее код завершения 0 (успех), справа от ||
команда игнорируется. Если команда слева возвращает другое значение (неудача), выполняется команда справа, и значение всего выражения есть код завершения правой команды. Иными словами, ||
представляет собой обычную операцию ИЛИ, которая не выполняет свою правую часть, если левая часть завершилась успешно. Соответственно &&
есть обычная операция И, выполняющая свою правую часть, только если левая часть завершилась успешно. Упражнение 5.4
Почему в команде
which
перед выходом из нее не восстанавливается значение PATH
из opath
? Упражнение 5.5
Если в языке
shell
используется esac
для завершения оператора case
и fi
для завершения оператора if
, почему для завершения оператора do
применяется done
? Упражнение 5.6
Введите в команду
which
флаг – а
, чтобы выводились все файлы из PATH
, а не только первый найденный. Подсказка:
match='exit 0'
Упражнение 5.7
Модифицируйте команду
which
так, чтобы она учитывала встроенные в язык shell
команды типа exit
. Упражнение 5.8
Модифицируйте команду
which
так, чтобы она проверяла права доступа файлов. Как изменить ее для получения диагностического сообщения, если файл не удалось найти? 5.3 Циклы
while
и until
: контроль входа в систему В гл. 3 цикл
for
использовался для нескольких итеративных программ. Обычно цикл for
охватывает множество имен файлов, как в 'for i in * .с'
, или все аргументы командного файла, как в 'for i in $*'
. Но циклы в языке shell
могут быть более общими, чем в этих идиомах, например цикл for
в команде which
. Имеются три вида циклов:
for
, while
и until
. Чаще всего используется цикл for
. В нем выполняется последовательность команд (тело цикла) для каждого элемента из множества слов. В большинстве случаев множество образуют просто имена файлов. В циклах while
и until
контроль над выполнением тела цикла осуществляется с помощью кода завершения команды. Тело цикла выполняется до тех пор, пока команда условия не вернет ненулевой код для while
или нуль для until
. Циклы while
и until
идентичны, за исключением кода завершения команды. Ниже приведены основные формы каждого цикла:
for i in список слов
do
тело цикла, $i последовательно получает значения элементов
done
for i (явно перечисляются аргументы командного файла, т.е. $*)
do
тело цикла, $i последовательно получает значения аргументов
done
while команда