Описание: Кандидат BSDA должен уметь просматривать и изменять переменные окружения временно и постоянно для любой оболочки поставляемой с системой BSD.
Практика: env(1), sh(1), csh(1), tcsh(1), environ(7)
Многие программы в UNIX берут настроечную
информацию из переменных окружения. Это хороший способ передать
в программу информацию, общую для разных программ. Например
программа df(1) будучи вызвана без аргументов
выводит информацию о свободном месте в единицах заданных в
переменной BLOCKSIZE
. Другие программы
(du(1), ls(1)) берут эту
же информацию из этой же переменной. Не будь механизма с
переменными окружения, нам понадобился бы некоторый общий реестр
с переменными, в котором скорее всего царил бы полный хаос.
Ниже приведён некоторый список переменных влияющих на поведение разнообразных программ и их значение. Список приведён по данным страницы man environ(7).
Таблица 7.1. Пользовательске переменные окружения [environ(7)]
Переменная | Описание |
---|---|
BLOCKSIZE |
Размер блока используемый некоторыми командами, в
частности df(1),
du(1) и ls(1).
BLOCKSIZE может быть указан в байтах,
а может в килобайтах, мегабайтах или гигабайтах, если
указать суффикс K, k, M, m, G или g. величины менее 512
или более 1G игнорируются
|
COLUMNS | Предпочитаемая пользователем ширина вывода для терминала. Используется такими утилитами, как ls(1) и who(1) для форматирования вывода на терминал. Если переменная неустановлена или пуста утилиты используют вызов ioctl(2) чтобы выяснить ширину терминала. |
EDITOR | Имя текстового редактора по умолчанию |
EXINIT | Список команд выполняемых при старте ex(1) и vi(1). |
HOME |
Пользовательский каталог. Устанавливается
login(1) из файла
passwd(5) .
|
LANG | Локаль. Эта переменная влияет на все программы использующие вызов setlocale(3). |
LC_ALL | Локаль. Переписывает значение переменных LC_COLLATE, LC_CTYPE, LC_MESSAGES, LC_MONETARY, LC_NUMERIC и LC_TIME. |
LC_COLLATE | Локаль. Сортировка строк. |
LC_CTYPE | Переменная для определения того, какие символы являются буквой, пробелом, цифрой и т.п. в данной локали. Какой порядок байт принят в локали. |
LC_MESSAGES | Локаль для диагностических сообщений |
LC_MONETARY | Локаль для указания формата валют. |
LC_NUMERIC | Локаль для отображения чисел |
LC_TIME | Локаль для отображения дат |
MAIL | Расположение почтового ящика пользователя (вместо используемого по умолчанию /var/mail), используется mail(1), sh(1) и многими другими почтовыми клиентами. |
NLSPATH | Список каталогов используемых для поиска сообщений диагностических сообщений LC_MESSAGES. См. catopen(3). |
PAGER | Название используемой по умолчанию программы-пейджера для постраничного вывода на экран (например less). Переменная используется mail(1), man(1), ftp(1), для вывода на экран сообщений неумещающихся на экран. |
PATH | Список каталогов разделённых двоеточием, в которых осуществляется поиск исполнимых файлов программами csh(1), sh(1), system(3), execvp(3), и пр. |
PRINTER | Имя используемого по умолчанию принтера для программ lpr(1), lpq(1), и lprm(1). |
PWD | Текущий рабочий каталог |
SHELL | Полный путь к пользовательской оболочке |
TERM |
Имя текущего терминала. Используется командами
nroff(1) или
plot(1) для определения
функциональности терминала. Полный список типов
терминалов приведён в файле /usr/share/misc/termcap
(termcap(5) ).
|
TERMCAP |
Строка описывающая терминал или, если начинается со
'/' — имя файла termcap. См.
TERMPATH ниже и
termcap(5)
|
TERMPATH |
перечень файлов termcap разделённых двоеточием или
пробелом, в которых ищется описание терминала.
Отсутствие TERMPATH эквивалентно
наличию переменной TERMPATH равной
$HOME/.termcap:/etc/termcap.
TERMPATH неиспользуется, если
TERMCAP содржит полный путь к файлу.
|
TMPDIR | Каталог для хранения временных файлов. Большинство приложений используют /tmp или /var/tmp. Установка этой переменной может заставить их использовать другое место. |
TZ |
Часовой пояс (timezone) для отображения дат. указывает
путь относительно каталога /usr/share/zoneinfo. Напимер,
чтобы узнать сколько времени в Москве env TZ=Europe/Moscow date ,
в Иркутске — env TZ=Asia/Irkuts date
См. также tzset(3).
|
USER | Имя пользователя (логин). |
Утилита env нужна для просмотра текущих переменных окружения
и/или запуска программ в специфическом окружении. Будучи
вызвана без аргументов она печатает список текущих
переменных и их значения. Можно задать команде env список
переменных и их значения и команду. Тогда эта команда будет
выполнена с указанными переменными. Опция
-i
может применяться для того, чтобы
env(1) не наследовала уже заданных
переменных. Чтобы узнать значение конкретной переменной
можно так же использовать команду
printenv(1). Например:
$
env | grep TZ TZ=Europe/Moscow$
date среда, 15 февраля 2006 г. 22:14:28 (MSK)$
env TZ=Asia/Irkutsk date четверг, 16 февраля 2006 г. 03:14:38 (IRKT)$
date среда, 15 февраля 2006 г. 22:14:41 (MSK)$
printenv TZ Europe/Moscow
Есть распространённая практика писать утилиту env(1) в «магичекую строку» (shebang), с которой обычно начинаются сценарии:
#!/usr/bin/env python
Таким способом программисты страхуются от того, что
интерпретатор python(1) может находиться
в неправильном месте. Так, в FreeBSD,
DragonFly BSD и
OpenBSD python(1)
будет скорее всего установлен в каталог /usr/local/bin
, в
NetBSD в /usr/pkg/bin
, в
Linux он возможно будет стоять в /usr/bin
. Чтобы магическая строка
всегда работала нужно либо переписывать её при инсталляции
скрипта (Обычно инсталляторы так и желают), либо писать как
выше в расчёте на то, что путь к языку
python(1) у пользователя прописан в
переменной PATH
.
Такой подход по ряду причин надо признать крайне неудачным.
Во-первых, такой скрипт будет работать не всегда. Будучи
вызван из crontab он может работать в ситуации, когда
переменная PATH
вообще не задана.
Кроме того, влияя на переменную PATH
пользователь может подсунуть
поддельный интерпретатор. Если вы выдали недобросовесному
судоеру права на запуск утилиты /root/bin/util.py
с правами root, а в
утилите в магической строке python(1)
вызывается через env(1), то судоер может
переопределив PATH
подсунуть поддельный
python и получить полный контроль над системой.
С другой стороны, прежде чем выдавать права
суперпользователя на исполнения некоторого скрипта, надо
хорошо понимать как работает интерпретатор, который вы
используете. Рассмотрим пример с тем же
python(1). Пусть у нас есть скрипт hello.py
такого содержания:
#!/usr/local/bin/python print "Hello World!"
Запустив этот скрипт командой
$
sudo env PYTHONINSPECT="1" ./test.py Hello World>>>
судоер по завершении скрипта получит приглашение командной строки интерпретатора python(1) через которую он получит полную власть над системой. Чтобы избежать этого, надо либо явно указать в скрипте инструкцию выхода:
#!/usr/local/bin/python import sys print "Hello World!" sys.exit()
либо ограничить пользователя в использовании переменных окружения:
#!/usr/bin/env -i /usr/local/bin/python print "Hello World!"
В интерпретаторе sh можно задать значение переменной путём
присваивания: var=value
, например
NEW=1
. После этого переменную
можно использовать, на её значение можно ссылаться из по
имени $NEW
, но она ещё не стала
переменной окружения. Чтобы эта переменная стала видна
программе как переменная окружения, её надо экспортировать
командой export.
$
NEW=1$
echo $NEW 1$
printenv NEW$
export NEW$
printenv NEW 1
Таким образом, переменные могут быть экспортированными и неэкспортированными. Только экспортированные переменные будут видны вызываемым программам и скриптам. Неэкспортированные переменные, тем не менее можно использовать в текущем сценарии. Они удобны тем, что не влияют на работу вызываемых программ.
Полный список переменных можно узнать командой set
без аргументов, а список
экспортированных переменных командой export
без аргументов.
В языке csh переменная устанавливается командой set
, а переменная окружения командой
setenv
. Причём переменные и
переменные окружения это два совершенно разных массива. Может
быть одновременно определена переменная и переменная окружения
с тем же именем, но другим значнием:
%
set NEW=1%
printenv NEW%
echo $NEW 1$
setenv NEW 2$
printenv NEW 2$
echo $NEW 1
Обратите внимание: команды set
и
setenv
имеют разный синтаксис.