Главная » Программирование для UNIX » Переменные оболочки UNIX

0

У оболочки есть  такие же  переменные, как и в  большинстве языков программирования  (в  терминах оболочки их  также  называют пара5 метрами). Такие строки, как $1, являются позиционными параметра5 ми  –  это  переменные, которые содержат аргументы,  передаваемые в командный файл.  Цифра  указывает  позицию в  командной строке. Уже упоминались такие переменные оболочки, как PATH (список каталогов  для поиска команд), HOME  (регистрационный каталог) и другие. Отличие от переменных обычного языка заключается в том,  что пере-

менная аргумента не может быть  изменена. Хотя PATH  – это переменная  со значением $PATH, но не существует переменной 1, значение которой равнялось бы $1. Так что $1 – это просто компактная запись перво го аргумента и ничего больше.

Переменные оболочки, не являющиеся позиционными параметрами, можно создавать, обращаться к ним и изменять их.  Например,

$ PATH=:/bin:/usr/bin

присваивание, которое изменяет путь поиска. По обе стороны от знака равенства не должно быть пробелов, а присваиваемое значение должно быть единым словом  (то есть необходимо заключить его в кавычки, если  слово  содержит  метасимволы, которые не должны  интерпретироваться оболочкой). Для  того чтобы получить значение переменной, надо поставить знак доллара перед ее именем:

$ PATH=$PATH:/usr/games

$ echo $PATH

:/usr/you/bin:/bin:/usr/bin:/usr/games

$ PATH=:/usr/you/bin:/bin:/usr/bin           Восстановление

$

Не  все  переменные оболочки являются  предопределенными.  Можно создавать новые  переменные, присваивая им  значения; по  традиции переменные со специальным смыслом записываются прописными буквами, а обычные имена – строчными (в нижнем регистре). Часто переменные используются для хранения длинных строк, например путей:

$ pwd

/usr/you/bin

$ dir=`pwd`                          Запомнить текущий каталог

$ cd /usr/mary/bin           Перейти в другое место

$ ln  $dir/cx .          Использовать переменную в имени файла

$ …                    Поработать некоторое время

$ 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                              Новая оболочка

$ echo $x

Только разделитель строк: x не определена в подоболочке

$ ctld                         Покинуть эту  оболочку

$                                   Обратно в исходную оболочку

$ echo $x

Hello                             x определена

$

Командный файл не  может изменить значение  переменной, потому  что он запускается подоболочкой:

$ echo ‘x="Good Bye"               Создать командный файл из двух строк…

> 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, а остальное пусто. Бы ло бы удобно, если бы передавались аргументы, но этого не происходит.

Другой способ установки значения переменной в подоболочке заключается в явном присваивании в командной строке перед самoй командой:

$ echo ‘echo  $x’  >echox

$ cx  echox

$ echo $x

Hello                                      Как и раньше

$ echox

$ x=Hi echox

В подоболочке x не установлена

Hi                                           Значение x передано в подоболочку

$

(Первоначально присваивания, занимающие любое место в командной строке, передавались команде, но это мешало dd(1).)

Механизм . следует использовать для того, чтобы  перманентно изме нить  значение переменной, а присваивания в командной строке – для  временных изменений. Для примера еще раз поищем команды в каталоге /usr/games при условии, что каталог не содержится в PATH:

$ ls /usr/games | grep  fort

fortune                                       Команда, выводящая афоризмы

$ fortune

fortune: not  found

$ echo $PATH

:/usr/you/bin:/bin:/usr/bin    /usr/games  не содержится в  PATH

$ PATH=/usr/games  fortune

Ring the  bell;  close the  book;  quench the  candle.

$ echo $PATH

:/usr/you/bin:/bin:/usr/bin      PATH  не изменена

$ cat  /usr/you/bin/games

PATH=$PATH:/usr/games                   games команда все еще здесь

$ . games

$ fortune

Premature  optimization is the  root of  all evil  –  Knuth

$ 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

I’d give  my  right arm to  be ambidextrous.

$ echo $PATH

:/usr/you/bin:/bin:/usr/bin                           Все еще не содержит

$ . games

$ echo $PATH

:/usr/you/bin:/bin:/usr/bin:/usr/games          Теперь содержит

$ fortune

He  who  hesitates is sometimes saved.

$

Первое обращение к games запускает командный файл в подоболочке, в которой PATH была временно изменена с тем,  чтобы  включить в себя

/usr/games. Вместо  этого  второй пример интерпретирует файл в теку щей  оболочке, с  пустой строкой $*,  так  что  в строке нет  команды, и PATH изменяется. В применении этих двух способов для games есть определенное трюкачество, в результате же появилось естественное и удобное средство.

Значение переменной можно сделать доступным в подоболочках с помощью команды оболочки export. (Можете подумать над тем,  почему нет способа экспортировать значение переменной из подоболочки в родительскую оболочку.) Приведем уже  рассмотренный выше пример, на этот раз используем экспортированную переменную:

$ x=Hello

$ export  x

$ sh                                        Новая оболочка

$ echo $x

Hello                                      x известна подоболочке

$ x=’Good Bye’                     Изменить ее значение

$ echo $x

Good  Bye

$ ctl–d                                  Покинуть эту  оболочку

$                                             Вернуться в исходную оболочку

$ echo $x

Hello                                        x все еще  Hello

$

Семантика команды export  не очевидна, но для повседневной работы достаточно эвристического правила: не экспортируйте временные пе-

ременные, экспортируйте переменные, которые хотите задать во всех оболочках и подоболочках (в том числе, например, оболочки, запускаемые командой ! редактора ed ). Поэтому следует экспортировать специальные переменные оболочки, такие как PATH и HOME.

Упражнение 3.13.  Почему мы всегда  включаем текущий каталог в переменную PATH? Куда он должен быть помещен? ~

Источник: Керниган Б., Пайк Р., UNIX. Программное окружение. – Пер. с англ. – СПб: Символ-Плюс, 2003. – 416 с., ил.

По теме:

  • Комментарии