Брайан Керниган - UNIX — универсальная среда программирования
- Название:UNIX — универсальная среда программирования
- Автор:
- Жанр:
- Издательство:Финансы и статистика
- Год:1992
- Город:Москва
- ISBN:5-289-00253-4
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Брайан Керниган - UNIX — универсальная среда программирования краткое содержание
В книге американских авторов — разработчиков операционной системы UNIX — блестяще решена проблема автоматизации деятельности программиста, системной поддержки его творчества, выходящей за рамки языков программирования. Профессионалам открыт богатый "встроенный" арсенал системы UNIX. Многочисленными примерами иллюстрировано использование языка управления заданиями shell.
Для программистов-пользователей операционной системы UNIX.
UNIX — универсальная среда программирования - читать онлайн бесплатно ознакомительный отрывок
Интервал:
Закладка:
$ cd $dir
Вернемся
$ pwd
/usr/you/bin
$
Встроенная в интерпретатор команда set
показывает значения всех определенных вами переменных. Для просмотра одной или двух переменных более подходит команда echo
:
$ set
HOME=/usr/you
IFS=
PATH=:/usr/you/bin:/bin/:/usr/bin
PS1=$
PS2=>
dir=/usr/you/bin
$ echo $dir
/usr/you/bin
$
Значение переменной связано с той копией интерпретатора, который создал ее, и автоматически не передается процессам — потомкам интерпретатора.
$ x=Hello
Создание x
$ sh
Новый shell
$ echo $x
Происходит только перевод строки,
x не определено в порожденном интерпретаторе
$ ctl-d
Возврат в исходный интерпретатор
$ echo $x
Hello
x по-прежнему определено
$
Это означает, что в командном файле нельзя изменить значение переменной, поскольку выполнением командного файла управляет порожденный интерпретатор:
$ echo 'x="Good bye"
Создание shell-файла из двух строк…
> echo $x' >setx
…для определения и печати x
$ cat setx
x="Good Bye"
echo $x
$ echo $x
Hello
x есть Hello в исходном интерпретаторе
$ sh setx
Good Bye
x есть Good Bye в порожденном интерпретаторе…
$ echo $x
Hello
…но по-прежнему есть Hello в текущем интерпретаторе
$
Однако бывают ситуации, когда было бы полезно изменять переменные интерпретатора в командном файле. Очевидным примером является файл, добавляющий новый каталог к вашей переменной PATH
. Поэтому интерпретатор предоставляет команду '.'
(точка), которая выполняет команды из файла в текущем, а не порожденном интерпретаторе. Первоначально это было задумано для удобства пользователей, чтобы они могли повторно выполнять свой файл .profile
, не входя заново в систему, но в принципе это открывает и другие возможности:
$ cat /usr/you/bin/games
PATH=$PATH:/usr/games
Добавим /usr/games к PATH
$ echo $PATH
:/usr/you/bin:/bin:/usr/bin
$ . games
$ echo $PATH
:/usr/you/bin:/bin:/usr/bin:/usr/games
$
Поиск файла для команды '.'
осуществляется с помощью переменной PATH
, так что его можно поместить в ваш каталог bin
.
Когда используется команда '.'
, только условно можно считать, что выполняется командный файл. Файл не "выполняется" в обычном смысле этого слова. Команды из него запускаются, как если бы вы ввели их в диалоговом режиме: стандартный входной поток интерпретатора временно переключается на файл. Поскольку файл читается, не нужно иметь право на его выполнение. Другое отличие состоит в том, что файл не получает аргументов командной строки; $1
, $2
и т.д. являются пустыми строками. Было бы неплохо, если бы аргументы передавались, но этого не происходит.
Есть еще один способ установить значение переменной в порожденном интерпретаторе — присвоить его явно в командной строке перед самой командой:
$ echo 'echo $x' >echox
$ cx echox
$ echo $x
Hello
Как и прежде
x не определено в порожденном интерпретаторе
$ x=Hi echox
Hi
Значение x передается порожденному интерпретатору
$
(Первоначально присваивания всюду в командной строке передавались команде, но это противоречило dd(1)
.)
Операцию '.'
следует использовать, чтобы навсегда изменить значение переменной, тогда как присваивания в командной строке предназначены для временных изменений. В качестве примера рассмотрим еще раз поиск команд в каталоге /usr/games
, не указанном в вашей переменной PATH
:
$ ls /usr/games | grep fort
fortune
Игровая команда fortune
$ fortune
fortune: not found
$ echo $PATH
:/usr/you/bin:/bin:/usr/bin
/usr/games не входит в PATH
$ PATH=/usr/games fortune
Позвони в звонок; закрой книгу; задуй свечу.
$ echo $PATH
:/usr/you/bin:/bin:/usr/bin
PATH не изменилось.
$ cat /usr/you/bin/games
команда games все еще здесь
$ . games
$ fortune
Непродуманная оптимизация - источник всех бед - Кнут
$ echo $PATH
:/usr/you/bin:/bin:/usr/bin:/usr/games
Сейчас PATH изменилось
$
Можно использовать оба средства в одном командном файле. Вы можете несколько видоизменить команду games
для запуска одной игровой программы без изменения переменной PATH
или постоянно переопределять PATH
, чтобы она включала /usr/games
:
$ cat /usr/you/bin/games
PATH=$PATH:/usr/games $*
Обратите внимание на $*
$ cx /usr/you/bin/games
$ echo $PATH
:/usr/you/bin:/bin:/usr/bin
/usr/games не входит
$ games fortune
Готов отдать свою правую руку, чтобы одинаково владеть обеими
$ echo $PATH
:/usr/you/bin:/bin:/usr/bin
Все еще не входит
$ . games
$ echo $PATH
:/usr/you/bin:/bin:/usr/bin:/usr/games
Теперь входит
$ fortune
Тот, кто медлит, иногда спасается
$
При первом обращении к games командный файл выполняется в порожденном интерпретаторе, в котором переменная PATH
временно изменена так, чтобы включать каталог /usr/games
. В то же время во втором примере файл обрабатывается текущим интерпретатором при значении $*
, являющемся пустой строкой, поэтому в строке нет команд и переменная PATH
изменяется. Применение команды games
в обоих случаях достаточно нетривиально, но в результате получаем удобное и естественное для использования средство.
Для того чтобы значение переменной было доступно в порожденном интерпретаторе, следует использовать команду export
языка shell
. (Вы можете поразмышлять о том, почему нет возможности экспортировать значение переменной от порожденного интерпретатора к порождающему его.) Приведем один из рассмотренных выше примеров, но теперь с экспортом переменной:
$ x=Hello
$ export x
$ sh
Новый интерпретатор
$ echo $x
Hello
x доступно в порожденном интерпретаторе
$ x='Good Bye'
Изменим значение x
$ echo $x
Good Bye
$ ctl-d
Выйдем из порожденного интерпретатора
$
Снова в исходном интерпретаторе
$ echo $x
Hello
x по-прежнему Hello
$
Семантика команды export
нетривиальна, но по крайней мере для повседневных нужд достаточно придерживаться основного правила: никогда не экспортируйте временные переменные, служащие для краткосрочных целей, и всегда экспортируйте переменные, необходимые вам во всех порожденных интерпретаторах (включая, например, интерпретаторы, запускаемые командой !
редактора ed
). Поэтому переменные, имеющие специальное значение для интерпретатора, такие, как PATH
и НОМЕ
, следует экспортировать.
Почему в значение переменной PATH
всегда включается текущий каталог? Куда его нужно поместить?
Интервал:
Закладка: