Рейтинг@Mail.ru
[Войти] [Зарегистрироваться]

Наши друзья и партнеры

UnixForum
Альтернативная энергия



Книги по Linux (с отзывами читателей)

Библиотека сайта или "Мой Linux Documentation Project"

Исследуем процесс загрузки Linux

(C) В.А.Костромин, 2007
(версия файла от 21.08.2007 г.)


Назад Оглавление Вперед

Этап 9: Старт оболочки Bash

Итак, демон getty запустил программу login, которая выводит предложение ввести имя пользователя (рис.3). Получив это имя, login обращается к файлу /etc/passwd за получением необходимых данных об этом пользователе, в частности, о его идентификаторе, идентификаторе группы, домашнем каталоге и о том, какую оболочку для него запускать. Одновременно выводится запрос на ввод пароля пользователя.
Когда пользователь введет пароль, программа login считывает его, криптует и сравнивает результат с тем, что лежит в соответствующей строке файла etc/shadow.

Если пользователь ввел правильный пароль, программа login, наконец, запускает командный процессор (оболочку). Как уже было сказано, какую именно оболочку запускать (ибо тут возможен довольно широкий выбор), определяется соответствующим полем в файле /etc/passwd.

Поскольку наиболее часто применяемым вариантом командной оболочки является bash, в дальнейшем будем рассматривать именно процесс загрузки этой программы (могу честно признаться, что главным основанием выбора этого варианта является то, что у меня используется именно эта оболочка и с другими я не работал).

9.1. Регистрационный shell

Теперь необходимо пояснить, что оболочка bash может запускаться в нескольких различных режимах. Рассказывать здесь полностью о том, чем режимы различаются, нет возможности, для этого загляните в man bash. Здесь же скажем только, что тот режим, который используется при запуске через программу login, называется режимом "интерактивного регистрационного shell или login shell" . Интерактивность в данном случае означает, что оболочка взаимодействует со стандартными потоками ввода-вывода, то есть стандартный входной и выходной потоки оболочки подключены к терминалу (просто существует и неинтерактивный режим запуска оболочки, например, для выполнения какого-то скрипта в фоновом режиме).

В случае запуска в режиме "login shell" процесс, в котором запускается оболочка, имеет тот же идентификатор, что и начальный getty-процесс, и является процессом, возглавляющим группу процессов. Чтобы убедиться в этом (вы же не обязаны верить мне на слово), выполните команду ps –axf, затем перейдите в свободную виртуальную консоль, запустите там программу Midnight Commander, вернитесь в ту консоль, где вы работали и снова запустите ps –axf. Сравнив вывод этой команды в первом и втором случае, вы увидите, что еще один процесс getty заменился на shell, причем из этой оболочки запущена команда mc.

В зависимости от режима запуска bash использует немного различные настроечные файлы. Какие именно из этих файлов используются в том или ином режиме запуска, рассказано в man bash (русский перевод этого руководства есть здесь). Я не буду приводить здесь описание всех вариантов, ограничусь только тем, который нас в данном случае интересует.

9.2. Запуск регистрационного экземпляра оболочки bash

При вызове bash в режиме интерактивного регистрационного интерпретатора команд, bash сначала читает и выполняет команды из файла /etc/profile, если этот файл существует. После прочтения этого файла, он последовательно ищет файлы ~/.bash_profile, ~/.bash_login и ~/.profile, читает и выполняет команды из первого же из них, который существует и доступен на чтение.

Давайте рассмотрим эти файлы из системы Mandriva Free 2007.1 и на этом примере разберем процесс загрузки оболочки bash в варианте регистрационного интерпретатора команд ("login shell").

Листинг 16. Файл /etc/profile системы Mandriva Free 2007.1.

# /etc/profile -*- Mode: shell-script -*- 
# (c) MandrakeSoft, Chmouel Boudjnah <chmouel@mandrakesoft.com>

loginsh=1

if [ "$UID" -ge 500 ] && ! echo ${PATH} |grep -q /usr/games ; then
    PATH=$PATH:/usr/games
fi

umask 022

USER=`id -un`
LOGNAME=$USER
MAIL="/var/spool/mail/$USER"
HISTCONTROL=ignoredups
HOSTNAME=`/bin/hostname`
HISTSIZE=1000

if [ -z "$INPUTRC" -a ! -f "$HOME/.inputrc" ]; then
    INPUTRC=/etc/inputrc
fi

# some old programs still use it (eg: "man"), and it is also
# required for level1 compliance for LI18NUX2000
NLSPATH=/usr/share/locale/%l/%N

export PATH PS1 USER LOGNAME MAIL HOSTNAME INPUTRC NLSPATH
export HISTCONTROL HISTSIZE 

for i in /etc/profile.d/*.sh ; do
	if [ -r $i ]; then
		. $i
	fi
done

unset i
Как видите,
  • вначале задается переменная loginsh, которая должна свидетельствовать о том что это именно "login sheell".
  • Далее проверяется, что пользователь не является привилегированным и если это так, то в число путей поиска добаляется каталог /usr/games (простому пользователю разрешается поиграть!).
  • Переменной umask присваивается значение 022, что означает что создаваемые данным пользователем файлы по умолчанию будут заданы права доступа ???
  • Задаются значения переменных:
    USER=`id -un`  
    LOGNAME=$USER        		# переменным  USER и LOGNAME присваивается имя пользователя;
    MAIL="/var/spool/mail/$USER"    # переменной MAIL присваивается имя каталога, 
    				# где будет храниться почта данного пользователя;
    HISTCONTROL=ignoredups		# если я правильно понимаю английский, будем 
    				# игнорировать повторы в истории команд; 
    HOSTNAME=`/bin/hostname`        # мне почему-то кажется, что где-то раньше мы эту 
    				# переменную уже задавали
    HISTSIZE=1000  			# задаем число команд, которые будут храниться в истории команд.
    
  • Если переменная INPUTRC имеет нулевую длину и (-a) файл $HOME/.inputrc не является простым файлом (то ли его не существует, то ли это сылка), то переменной INPUTRC присваивается значение /etc/inputrc.
  • Для некоторых старых программ (например, man) требуется задать переменную NLSPATH=/usr/share/locale/%l/%N
  • Экспортируются значения всех заданных переменных, чтобы они были доступны для всех процессов, запускаемых из данного экземпляра оболочки.
  • Ну, и наконец, запускаются на выполнение все скрипты (файлы с расширением .sh) из каталога /etc/profile.d/, если только такие файлы существуют и для них установлено право на чтение.
В моей системе в каталоге /etc/profile.d/ файлов с расширением .sh нашлось 19 штук (и еще примерно столько же - срасширением .csh). Немного поразмыслив я решил не включать их все в основной текст заметки, а привести в виде отдельного приложения. Если мы просмотрим это приложение, то увидим, что скрипты из /etc/profile.d/ выполняют следующие задачи:
  • - устанавливаются параметры локализации (скрипт 10lang.sh);
  • - задаются общесистемные алиасы (скрипт alias.sh); причем вначале проверяется, не отказался ли пользователь от использования общесистемных алиасов; между прочим, среди этих общесистемных алиасов есть очень интересные, загляните в этот список в вашей системе и, возможно, вы будете использовать сокращенные написания некоторых часто употребляемых команд;
  • - настройки клавиатуры немного изменяются в зависимости от аппаратной архитектуры (скрипт configure_keyboard.sh);
  • - задаются установки, связанные с безопасностью (скрипт msec.sh);
  • - создается директория для временных файлов (если ее не было) и указание на нее запоминается в переменной TMPDIR (скрипт tmpdir.sh);
  • - корректируется поведение клавиши NumLock (скрипт numLock.sh);
  • - значения многих переменных сразу после их задания экспортируются.
и так далее.

Как было сказано в начале этого раздела, после общесистемного файла /etc/profile оболочка bash последовательно ищет файлы ~/.bash_profile, ~/.bash_login и ~/.profile и выполняет команды из этих файлов. Файлов ~/.bash_login и ~/.profile в моей системе не нашлось, а файл ~/.bash_profile приведен в листинге 36:

Листинг 36. Файл ~/.bash_profile системы Mandriva Free 2007.1.

# .bash_profile

# Initialize keychain if needed
if [ -r $HOME/.ssh/identity -o -r $HOME/.ssh/id_dsa -o -r $HOME/.ssh/id_rsa ]; then
 	if [ ! -d $HOME/.keychain ]; then
	        keychain
        fi
fi

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
	. ~/.bashrc
fi

# User specific environment and startup programs

PATH=$PATH:$HOME/bin

export PATH
unset USERNAME
Как видите в этом скрипте корректируется переменная PATH (в список путей для поиска добавляется каталог ~/bin) и вызывается на выполнение еще один скрипт - ~/.bashrc, причем комментарий к этому вызову сообщает, что тем самым снова задаются алиасы и функции. Впрочем, как видно из листинга 37, в самом вызываемом скрипте мало что задается - он всего лишь содержит вызов общесистемного скрипта /etc/bashrc (см. листинг 38).

Листинг 37. Файл ~/.bashrc системы Mandriva Free 2007.1.

# .bashrc

# User specific aliases and functions

# Source global definitions
if [ -f /etc/bashrc ]; then
	. /etc/bashrc
fi

Листинг 38. Файл /etc/bashrc системы Mandriva Free 2007.1.

# /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

# are we an interactive shell?
if [ "$PS1" ]; then
    case $TERM in
	xterm*)
	    PROMPT_COMMAND='echo -ne "\033]0;${USER}@${HOSTNAME}: ${PWD}\007"'
	    ;;
	*)
	    ;;
    esac
    [ "$PS1" = "\\s-\\v\\\$ " ] && PS1="[\u@\h \W]\\$ "
    
    if [ -z "$loginsh" ]; then # We're not a login shell
	# Not all scripts in profile.d are compatible with other shells
	# TODO: make the scripts compatible or check the running shell by
	# themselves.
	if [ -n "${BASH_VERSION}${KSH_VERSION}${ZSH_VERSION}" ]; then
            for i in /etc/profile.d/*.sh; do
	        if [ -x $i ]; then
	            . $i
	        fi
	    done
	fi
    fi
fi

unset loginsh

На этом загрузка интерактивного регистрационной оболочки завершена и пользователь может работать в системе. При этом он получает окружение, сформированное перечисленными файлами скриптов.

Отмечу, что если в Mandriva файла ~/.profile не оказалось, то в системе OpenSUSE 10.2 от существует. В комментариях внутри этого файла говорится, что этот файл прочитывается, то есть вызывается на выполнение каждый раз, когда стартует регистрационный шелл. Все другие интерактивные оболочки вызывают только файл ~/.bashrc.

Еще раз приведем список файлов, оказывающих влияние на то, какую именно конфигурацию оболочки мы получим после запуска. Этот список выглядит примерно следующим образом:

/etc/passwd
Глобальный файл, содержащий регистрационную информацию о пользователе

/etc/shadow
Глобальный файл паролей;

/etc/profile
Общесистемный файл инициализации (файл профилей), выполняется начальными командными интерпретаторами. Устанавливает общесистемную переменную $PATH и другие важнейшие переменные; заглянув в него, вы увидите, что в нем вызываются все файлы из подкаталога /etc/profile.d, в частности, файл, задающий параметры локализации системы;

/etc/bashrc
Глобальный файл конфигурации bash, устанавливает синонимы (алиасы) и функции, и т.п.;
/etc/issue
Содержит сообщение, выдаваемое на терминал перед входом в систему (перед запросом имени и пароля); однако редактировать этот файл с целью изменения текста сообщения не стоит, потому что сам он формируется инициализационным скриптом /etc/rc.d/rc.local;
/etc/motd
Устанавливает сообщение, выдаваемое пользователю после входа в систему (после правильного ввода пароля).
~/.bash_profile
Личный файл инициализации (файл личного профиля), выполняется начальными командными интерпретаторами
~/.bashrc
Отдельный файл начального запуска для интерактивных командных интерпретаторов
~/.inputrc
Отдельный файл инициализации библиотеки readline
~/.profile
Личный файл инициализации (файл личного профиля), выполняется начальными командными интерпретаторами

Если вы что-то хотите поменять в той конфигурации, которую получаете при входе в систему, то, очевидно, имеет смысл подкорректировать ваш личный файл профиля ~/.bash_profile или файл ~/.bashrc.


Примечание: При завершении работы в качестве начального командного интерпретатора bash читает и выполняет команды в файле ~/.bash_logout, если он существует. В моем случае файл этот оказался на удивление простым (листинг 39):

Листинг 39. Файл ~/.bash_logout системы Mandriva Free 2007.1.

# ~/.bash_logout

clear

Назад Оглавление Вперед


Эта статья еще не оценивалась
Вы сможете оценить статью и оставить комментарий, если войдете или зарегистрируетесь.
Только зарегистрированные пользователи могут оценивать и комментировать статьи.

Комментарии отсутствуют