Чтение онлайн

на главную - закладки

Жанры

UNIX — универсальная среда программирования
Шрифт:

5.2 Что представляет собой команда

which
?

При обзаведении собственными версиями команд, аналогичных

cal
, возникает ряд трудностей. В частности, когда вы работаете как пользователь Мэри и вошли в систему под именем
mary
, то, вводя команду
cal
, получаете стандартную версию команды вместо новой, если, конечно, не установили в своем каталоге
bin
связь с новой командой
cal
. Это может привести к путанице: вспомните, что сообщения об ошибках в исходной, команде
cal
не очень вразумительны. Мы привели всего лишь один пример возникающих трудностей. Поскольку интерпретатор осуществляет поиск команд среди каталогов, задаваемых переменной
PATH
, всегда есть вероятность столкнуться не с той версией
команды, которую вы ожидали. Например, если вы задали команду, скажем
echo
, имя выполняемого на самом деле файла будет
./echo
,
/bin/echo
,
/usr/bin/echo
или какое-то другое в зависимости от компонентов вашей переменной
PATH
и от того, где находятся файлы. Может случиться, что в вашей последовательности поиска ранее, чем вы ожидали, окажется выполняемый файл с правильным именем, но не с теми результатами. Наиболее типичным примером в такой ситуации является команда
test
, которую мы обсудим позднее. Ее название настолько распространено для временной версии программы, что вызовы "не тех" команд
test
происходят раздражающе часто [12] . Здесь весьма полезным средством явилась бы команда, которая помогла бы выяснить, какая версия программы должна выполняться.

12

Позднее будет показано, как обойти эту трудность в командных файлах, где обычно используется команда

test
.

Один из вариантов решения — цикл поиска по каталогам, указанным в

PATH
, выполняемого файла с данным именем. В гл. 3 мы использовали цикл
for
по именам файлов и аргументам. Здесь же нужен такой цикл:

for i in компонента в PATH

do

 если заданное имя в каталоге i

печать полного путевого имени

done

Поскольку любую команду можно запустить внутри символов слабого ударения очевидное решение состоит в том, чтобы запустить

sed
по значению
PATH
, заменив двоеточия на пробелы. Мы можем проверить это с помощью нашего старого друга
echo
:

$ echo $PATH

:/usr/you/bin:/bin:/usr/bin
4 компонента

$ echo $PATH | sed 's/:/ /a'

/usr/you/bin /bin /usr/bin
Только три выдано!

$ echo `echo $PATH | sed 's/:/ /g'`

/usr/you/bin /bin /usr/bin
По-прежнему только три

$

Однако такое решение проблематично. Пустая строка в

PATH
служит синонимом
'.'
. Поэтому перевод двоеточий в пробелы не слишком удачен — теряется информация о пустых компонентах. Для создания правильного списка каталогов пустую компоненту
PATH
нужно перевести в точку. Пустая компонента может быть в середине, начале или конце строки, так что вам придется потрудиться, чтобы учесть все возможные случаи:

$ echo $PATH | sed 's/^:/./

> s/::/:.:/g

> s/:$/:./

> s/:/ /g'

. /usr/you/bin /bin /usr/bin

$

Мы могли бы записать это с помощью четырех отдельных команд

sed
, но так как редактор
sed
производит замены по порядку, можно выполнить все операции за один вызов.

После задания каталогов в компонентах

PATH
упомянутая выше команда
test(1)
может вывести сообщение о том, существует ли файл в каждом каталоге. В принципе команда
test
— одна из самых "неуклюжих" программ UNIX. Например, команда
"test -r файл"
проверяет, существует ли файл и можно ли его читать;
"test -w файл"
проверяет, существует ли файл и можно ли в него писать, но в седьмой версии нет команды
test -х
(хотя в System V и других версиях есть), а именно она нам и нужна. Мы примем, что обращение
"test -f файл"
будет проверять, существует ли файл и не является ли он каталогом, т.е. представляет ли он собой обычный файл. Но вам следует обратиться
к соответствующей странице справочного руководства, поскольку имеет хождение несколько версий.

Каждая команда вырабатывает код завершения — значение, передаваемое интерпретатору и показывающее, что произошло. Это небольшое целое число, которое устанавливается по соглашению. Так, нуль может означать "истину" (команда успешно завершена), а ненулевое значение трактуется как "ложь" (выполнение команды было неудачным). Обратите внимание на то, что выбранные здесь значения противоположны значениям истины и лжи в языке Си.

Поскольку ложь может представлять множество различных значений, причина неудачи обозначается кодом завершения по лжи. Например, команда grep возвращает 0, если произошло сопоставление, 1 — если сопоставления не было, и 2 — в случае ошибки в шаблоне или именах файлов. Каждая программа возвращает код завершения, хотя обычно нас не интересует его значение. Команда

test
неординарна: ее единственное назначение состоит в передаче кода завершения. Она ничего не выводит и не изменяет файлы.

Интерпретатор хранит код завершения последней программы в переменной

$?
:

$ cmp /usr/you/.profile /usr/you/.profile

$
Выдачи нет, файлы совпадают

$ echo $?

0
0 означает успех, файлы идентичны

$ cmp /usr/you/.profile /usr/mary/.profile

/usr/you/.profile /usr/mary/.profile differ: char 6, line 3

$ echo $?

1
He нуль означает, что файлы различны

$

У некоторых команд, таких, как

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

Поделиться:
Популярные книги

#Бояръ-Аниме. Газлайтер. Том 36

Володин Григорий Григорьевич
36. История Телепата
Фантастика:
боевая фантастика
аниме
фэнтези
5.00
рейтинг книги
#Бояръ-Аниме. Газлайтер. Том 36

Изгои

Владимиров Денис
5. Глэрд
Фантастика:
фэнтези
боевая фантастика
5.00
рейтинг книги
Изгои

Распутье

Басаргин Иван Ульянович
Сибириада
Проза:
военная проза
историческая проза
5.00
рейтинг книги
Распутье

Мистика

Гейман Нил
Детективы:
классические детективы
исторические детективы
7.29
рейтинг книги
Мистика

Убивать чтобы жить 2

Бор Жорж
2. УЧЖ
Фантастика:
героическая фантастика
боевая фантастика
рпг
5.00
рейтинг книги
Убивать чтобы жить 2

Адепт

Листратов Валерий
4. Ушедший Род
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Адепт

Убивать чтобы жить 5

Бор Жорж
5. УЧЖ
Фантастика:
боевая фантастика
космическая фантастика
рпг
5.00
рейтинг книги
Убивать чтобы жить 5

Лекарь Империи 6

Карелин Сергей Витальевич
6. Лекарь Империи
Фантастика:
городское фэнтези
боевая фантастика
аниме
попаданцы
5.00
рейтинг книги
Лекарь Империи 6

Атаман царского Спецназа

Корчевский Юрий Григорьевич
Боевая фантастика Ю. Корчевского
Фантастика:
боевая фантастика
попаданцы
альтернативная история
6.00
рейтинг книги
Атаман царского Спецназа

Эмиссар

Листратов Валерий
8. Ушедший Род
Фантастика:
боевая фантастика
аниме
попаданцы
7.50
рейтинг книги
Эмиссар

Наша навсегда

Зайцева Мария
2. Наша
Любовные романы:
современные любовные романы
эро литература
5.00
рейтинг книги
Наша навсегда

Ермак. Телохранитель

Валериев Игорь
2. Ермак
Фантастика:
альтернативная история
7.00
рейтинг книги
Ермак. Телохранитель

Геном хищника. Книга седьмая

Гарцевич Евгений Александрович
7. Я - Легенда!
Фантастика:
боевая фантастика
рпг
фэнтези
попаданцы
5.00
рейтинг книги
Геном хищника. Книга седьмая

Двойник короля 21

Скабер Артемий
21. Двойник Короля
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Двойник короля 21