ГлавноеМы уже упоминали несколько переменных окружения, таких как PATH и HOME. До сих пор мы видели только примеры, в которых они используются в оболочке для определенной цели. Но в Linux существует множество других утилит, для нормальной работы которых необходима информация о вас.Какая еще информация нужна программам, кроме путей и домашних каталогов? Многим программам необходима информация о том, какой терминал вы используете; эта информация хранится в переменной TERM. В текстовом режиме, это будет эмуляция терминала linux, в графическом режиме, скорее всего, вы используете xterm. Многим программам требуется информация о предпочитаемом вами редакторе на случай, если они должны будут запускать редактор как дочерний процесс. Оболочка, которую вы используете, хранится в переменной SHELL, тип операционной системы - в OS и так далее. Список всех текущих переменных, определенных для вашей сессии, можно посмотреть, введя команду printenv. Переменные окружения управляются оболочкой. В отличие от регулярных переменных оболочки, переменные окружения наследуются любой программой, которую вы запускаете, в том числе другой оболочкой. Новым процессам присваиваются копии этих переменных; процессы могут их читать, изменять и, в свою очередь, передавать собственным дочерним процессам. В именах переменных нет ничего особенного, за исключением того, что по соглашению используют прописные буквы. Вы можете придумать любое имя, какое захотите, хотя существуют стандартные переменные, которые являются достаточно важными, поэтому они одинаковы во всех системах Linux, например PATH и HOME. Экспорт переменныхСодержимое отдельных переменной обычно отображается с помощью команды echo, как в этих примерах:debby:~> echo $PATH /usr/bin:/usr/sbin:/bin:/sbin:/usr/X11R6/bin:/usr/local/bin debby:~> echo $MANPATH /usr/man:/usr/share/man/:/usr/local/man:/usr/X11R6/manЕсли вы хотите изменить содержимое переменной таким, чтобы она была полезна для других программ, вам следует экспортировать новое значение из вашего окружения в окружение, которое запускают эти программы. Типичным примером является экспорт переменной PATH. Вы можете объявить ее добавлением очередного пути, например, с тем чтобы иметь возможность играть в симулятор полетов, который находится в /opt/FlightGear/bin: debby:~> PATH=$PATH:/opt/FlightGear/binТакая запись указывает оболочке искать программ не только в текущем пути $PATH, но и в дополнительном каталоге /opt/FlightGear/bin. Но если новое значение переменной PATH не известно окружению, то работать ничего не будет: debby:~> runfgfs bash: runfgfs: command not foundВ Bash мы обычно делаем это с помощью одного элегантного шага: export VARIABLE=value Тот же самый способ используется для переменной MANPATH, которая сообщает команде man, где искать сжатые man-страницы. Когда новые программы устанавливаются в новые или необычные каталоги, документация для них, вероятно, также будет в нестандартных каталогах. Если вы хотите прочитать справочные страницы этих новых программ, расширьте переменную MANPATH: debby:~> export MANPATH=$MANPATH:/opt/FlightGear/man debby:~> echo $MANPATH /usr/man:/usr/share/man:/usr/local/man:/usr/X11R6/man:/opt/FlightGear/manВы можете избежать повторного ввода этой команды в каждом окне, которое вы открываете, добавив эту строку в один из ваших установочных файлов оболочки, см. Раздел "Установочные файлы shell". Зарезервированные переменныеСледующая таблица дает обзор наиболее распространенных предопределенных переменных:Таблица. Стандартные переменные окружения
Установочные файлы shellПри вводе команды ls -al для получения расширенного списка всех файлов, в том числе начинающихся с точки, содержащихся в вашем домашнем каталоге, вы увидите один или несколько файлов, начинающихся с . и заканчивающихся на rc. Для Bash это будет .bashrc. Это копия общесистемного конфигурационного файла /etc/bashrc.При входе логина в shell, login выполнит идентификацию, установит окружение и запустит вашу оболочку. В случае bash следующим шагом будет чтение общего профиля из /etc, если такой файл существует. Затем bash ищет ~/.bash_profile, ~/.bash_login и ~/.profile в указанном порядке, читает и выполняет команды из первого, который существует и который можно прочитать. Если таких файлов нет, то используется /etc/bashrc. Когда происходит выход их оболочки, bash считывает и выполняет команды из файла ~/.bash_logout, если он существует. Эта процедура подробно описана в man-страницах login и bash. Стандартный набор установочных файловПример /etc/profileДавайте посмотрим на некоторые из этих конфигурационных файлов. Первый для чтения — это /etc/profile, в котором устанавливаются такие важные переменные, как PATH, USER и HOSTNAME:debby:~> cat /etc/profile # /etc/profile # System wide environment and startup programs, for login setup # Functions and aliases go in /etc/bashrc # Path manipulation if [ `id -u` = 0 ] && ! echo $PATH | /bin/grep -q "/sbin" ; then PATH=/sbin:$PATH fi if [ `id -u` = 0 ] && ! echo $PATH | /bin/grep -q "/usr/sbin" ; then PATH=/usr/sbin:$PATH fi if [ `id -u` = 0 ] && ! echo $PATH | /bin/grep -q "/usr/local/sbin" then PATH=/usr/local/sbin:$PATH fi if ! echo $PATH | /bin/grep -q "/usr/X11R6/bin" ; then PATH="$PATH:/usr/X11R6/bin" fiЭти строки проверяют устанавливаемые пути: если root открывает оболочку (ID пользователя 0), проверяется пути /sbin, /usr/sbin и /usr/local/sbin. Если нет, то они добавляются. Для всех проверяется путь /usr/X11R6/bin. # No core files by default ulimit -S -c 0 > /dev/null 2>&1Все, что не нужно отправляется в /dev/null, если пользователь не меняет эту настройку. USER=`id -un` LOGNAME=$USER MAIL="/var/spool/mail/$USER" HOSTNAME=`/bin/hostname` HISTSIZE=1000Здесь общим переменным назначаются их стандартные значения. if [ -z "$INPUTRC" -a ! -f "$HOME/.inputrc" ]; then INPUTRC=/etc/inputrc fiЕсли переменная INPUTRC не установлена, и нет .inputrc в домашнем каталоге пользователя, то будет загружен файл, отвечающий за ввод по умолчанию. export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE INPUTRCВсе переменные экспортируются, поэтому они доступны для других программ, запрашивающих информацию о вашем окружении. Каталог profile.dfor i in /etc/profile.d/*.sh ; do if [ -r $i ]; then . $i fi done unset iВсе читаемые скрипты shell из каталога /etc/profile.d читаются и выполняются. Это то, что делает возможным color-ls, похожесть vi на vim, локальные настройки и т.д. Временная переменная i не устанавливается для предотвращения неадекватного поведения оболочки позже. Пример .bash_profileЗатем bash ищет .bash_profile в домашнем каталоге пользователя:debby:~> cat .bash_profile ##################################################### # # # .bash_profile file # # # # Executed from the bash shell when you log in. # # # ##################################################### source ~/.bashrc source ~/.bash_loginВ файле содержаться указания оболочке сначала прочитать ~/.bashrc, потом ~/.bash_login. При работе с окружением оболочки вы будете сталкиваться с встроенной в shell командой source достаточно часто: она используется для применения изменений конфигурации к текущему окружению. Пример .bash_loginФайл ~/.bash_login определяет по умолчанию защиту файлов, устанавливая значение umask, см. Раздел "Вступление в другую группу". Файл ~/.bashrc используется для определения группы пользовательских псевдонимов, функции и личные переменных окружения. Сначала читается /etc/bashrc, который описывает стандартное приглашение (PS1) и значение по умолчанию umask. После этого вы можете добавить собственные настройки. Если нет ~/.bashrc, то по умолчанию читается /etc/bashrc.Пример /etc/bashrcВаш файл /etc/bashrc может выглядеть следующим образом:debby:~> cat /etc/bashrc # /etc/bashrc # System wide functions and aliases # Environment stuff goes in /etc/profile # by default, we want this to get set. # Even for non-interactive, non-login shells. if [ `id -gn` = `id -un` -a `id -u` -gt 99 ]; then umask 002 else umask 022 fiЭти строки устанавливают значение umask. Затем, в зависимости от типа shell, устанавливается приглашение: # are we an interactive shell? if [ "$PS1" ]; then if [ -x /usr/bin/tput ]; then if [ "x`tput kbs`" != "x" ]; then # We can't do this with "dumb" terminal stty erase `tput kbs` elif [ -x /usr/bin/wc ]; then if [ "`tput kbs|wc -c `" -gt 0 ]; then # We can't do this with "dumb" terminal stty erase `tput kbs` fi fi fi case $TERM in xterm*) if [ -e /etc/sysconfig/bash-prompt-xterm ]; then PROMPT_COMMAND=/etc/sysconfig/bash-prompt-xterm else PROMPT_COMMAND='echo -ne "\033]0;${USER}@${HOSTNAME%%.*}:\ ${PWD/$HOME/~}\007"' fi ;; *) [ -e /etc/sysconfig/bash-prompt-default ] && PROMPT_COMMAND=\ /etc/sysconfig/bash-prompt-default ;; esac [ "$PS1" = "\\s-\\v\\\$ " ] && PS1="[\u@\h \W]\\$ " if [ "x$SHLVL" != "x1" ]; then # We're not a login shell for i in /etc/profile.d/*.sh; do if [ -x $i ]; then . $i fi done fi fi Пример .bash_logoutВо время выхода из системы, выполняются команды из ~/.bash_logout, которые могут, например, очищать терминал, так что у вас появляется чистое окно при входе из удаленного сеанса или при выходе из системной консоли:debby:~> cat .bash_logout # ~/.bash_logout clearДавайте ближе рассмотрим, как эти скрипты работают в следующем разделе. Храните info bash под рукой. Приглашение BashВведениеПриглашение Bash может делать гораздо больше, чем отображение такой простой информации, как имя пользователя, имя машины и некоторое указание на текущий рабочий каталог. Мы можем добавить другую информацию, такую как дата и время, количество подключенных пользователей и т.д.Однако, прежде чем мы начнем, сохраним наше текущее приглашение в другую переменную окружения: [jerry@nowhere jerry]$ MYPROMPT=$PS1 [jerry@nowhere jerry]$ echo $MYPROMPT [\u@\h \W]\$ [jerry@nowhere jerry]$Когда мы теперь будем изменять строку приглашения, например, с помощью команды PS1="->", то всегда сможем получить нашу оригинальную строку обратно с помощью команды PS1=$MYPROMPT. Конечно, вы получите ее обратно, и когда подключитесь снова; так будет до тех пор, пока вы возитесь с приглашением в командной строке и не вставляете его в файл конфигурации оболочки. Некоторые примерыДля того, чтобы понять эти приглашения и используемые управляющие последовательности, обратитесь к info- и man-страницам Bash.
Если вам захочется, то приглашения могут выполнять shell-скрипты и вести себя по-разному в зависимости от условий. У вас может даже строка приглашения играть мелодию при выполнении команды, хотя это вам быстро надоест. Более подробную информацию можно найти в Bash-Prompt HOWTO. Сценарии оболочкиЧто такое сценарии?Скрипт оболочки, как мы видели в примерах конфигурации shell, представляет собой текстовый файл, содержащий команды оболочки. Когда такой файл используется в качестве первого аргумента без опции при вызове Bash, и без опций -c или -s, Bash считывает и выполняет команды из файла, затем выходит. Этот режим работы создает неинтерактивную оболочку. Когда Bash запускает shell-скрипт, он устанавливает специальный параметр 0 к имени файла, а не имя к оболочке, и позиционные параметры (все, что следует за именем скрипта) устанавливаются в остальные аргументы, если таковые задаются. Если дополнительные аргументы не задаются, позиционные параметры не включаются.Скрипт оболочки можно сделать исполняемым с помощью команды chmod за счет включения бита исполнения. Когда Bash находит такой файл при поиске в PATH по отношению к команде, он порождает подоболочку для его выполнения. Другими словами, выполнение filename ARGUMENTS эквивалентно выполнению bash filename ARGUMENTS если "filename" представляет собой исполняемый скрипт. Эта подоболочка инициализирует себя, так что эффект такой, как если бы новая оболочка интерпретировала сценарий, с тем исключением, что места команд, запомненные родителем (см. hash в info-страницах), сохраняются ребенком. Большинство версий UNIX наделяют эту часть команд операционной системы исполняемым механизмом. Если первая строка сценария начинается с двух символов "#!", оставшаяся часть строки указывает интерпретатор для программы. Таким образом, вы можете указать bash, awk, perl или другой интерпретатор или оболочку и писать остальную часть файла сценария на этом языке. Аргументы для интерпретатора состоят из одного дополнительного аргумента, который следует за именем интерпретатора в первой строке файла сценария, после следует имя файла сценария, а затем остальные аргументы. Bash будет выполнять это действие на операционных системах, которые не обрабатывают это самостоятельно. Сценарии Bash часто начинаются с #! /bin/bash (предполагая, что Bash была установлена в /bin), так как это гарантирует использование Bash для интерпретации сценариев, даже если скрипт выполняется под другой оболочкой. Некоторые простые примерыОчень простой скрипт, состоящий только из одной команды, которая приветствует пользователя, выполняется так:[jerry@nowhere ~] cat hello.sh #!/bin/bash echo "Hello $USER"Сценарий фактически состоит только из одной команды echo, которая использует значение ($) переменной окружения USER, чтобы напечатать строку, настроенную на пользователя, который вызывает скрипт. Другой однострочный пример, используемый для отображения подключенных пользователей: #!/bin/bash who | cut -d " " -f 1 | sort -uВот скрипт, состоящий из несколько строк, которые я использую, чтобы создать резервные копии всех файлов в каталоге. Сначала скрипт создает список всех файлов в текущем каталоге и помещает его в переменную LIST. Затем он устанавливает имя копии для каждого файла, и затем копирует файл. Для каждого файла выводится сообщение: tille:~> cat bin/makebackupfiles.sh #!/bin/bash # make copies of all files in a directory LIST=`ls` for i in $LIST; do ORIG=$i DEST=$i.old cp $ORIG $DEST echo "copied $i" doneПросто ввод строки подобной mv * *.old не будет работать, как вы заметите при попытке выполнить это на ряд тестовых файлов. Команда echo была добавлена для отображения какой-либо деятельности. echo обычно полезна, когда сценарий не работает: постепенно просматривая код, вы найдете ошибку в кратчайшие сроки. Каталог /etc/rc.d/init.d содержит множество примеров. Давайте посмотрим на этот сценарий, который управляет фиктивным сервером IcanSeeYou: #!/bin/sh # description: ICanSeeYou allows you to see networked people # process name: ICanSeeYou # pidfile: /var/run/ICanSeeYou/ICanSeeYou.pid # config: /etc/ICanSeeYou.cfg # Source function library. . /etc/rc.d/init.d/functions # See how (with which arguments) we were called. case "$1" in start) echo -n "Starting ICanSeeYou: " daemon ICanSeeYou echo touch /var/lock/subsys/ICanSeeYou ;; stop) echo -n "Shutting down ICanSeeYou: " killproc ICanSeeYou echo rm -f /var/lock/subsys/ICanSeeYou rm -f /var/run/ICanSeeYou/ICanSeeYou.pid ;; status) status ICanSeeYou ;; restart) $0 stop $0 start ;; *) echo "Usage: $0 {start|stop|restart|status}" exit 1 esac exit 0Во-первых, размещается . (точка), которая управляет множеством функций оболочки и используется практически во всех скриптах в /etc/rc.d/init.d. Затем размещается команда case, которая определяет 4 различных способа выполнения сценария. Например, это может быть ICanSeeYou start. Решением в этом случае будет чтение (первого) аргумента сценария с выражением $1. Когда дается не совместимый вход, то срабатывает код, отмеченный звездочкой, в котором скрипт выдает сообщение об ошибке. Список case заканчивается инструкцией esac. В случае start программа сервера запускается как демон, и назначаются ID процесса и шлюз. В случае stop процесс сервера сходит на нет и останавливается, шлюз и PID удаляются. Опции, такие как опции daemon и функции как killproc определены в файле /etc/rc.d/init.d/functions. Эта установка специфична для дистрибутива, используемого в этом примере. Запускающие скрипты в вашей системе могут использовать другие функции, определенные в других файлах, или вообще никакие. В случае успеха сценарий возвращает код выхода нуля к его родителю. Этот сценарий является прекрасным примером использования функций, которые позволяют легче читать сценарий и делать работу быстрее. Заметьте, что здесь используется sh вместо bash, чтобы сделать их полезными для более широкого круга систем. В системе Linux, вызывая bash как sh, результаты в оболочке работают в POSIX-совместимом режиме. Man-страницы bash содержат больше информации об объединении команд, for- и while-петлях, регулярных выражений, а также примеры. Понятный Bash для системных администраторов и опытных пользователей, с упражнениями, от того же автора, как "Введение в руководство Linux", находится на http://tille.garrels.be/training/bash/. Подробное описание особенностей Bash и приложений есть в справочном руководстве "Продвинутые сценарии Bash". |