RUNSCRIPT¶
НАЗВАНИЕ¶
runscript - интерпретатор сценариев оболочки для служб
СИНТАКСИС¶
runscript [-D , -nodeps ] [-d , -debug ] [-s , -ifstarted ] [-Z , -dry-run ] [команда ... ]
ОПИСАНИЕ¶
runscript фактически представляет собой интерпретатор shell-сценариев, предоставляющий простой интерфейс для зачастую сложных системных команд и демонов. Когда какая-либо служба вызывает команду, она сначала загружает множественный конфигурационный файл, затем управляющий им конфигурационный файл, далее /etc/rc.conf и, наконец, сам сценарий. Здесь runscript запускает заданную команду.
Команды определяются в сценарии как функции оболочки. Ниже приведен перечень функций, по умолчанию доступных для всех сценариев запуска:
describe
Описывает поведение службы и каждую команду, определяемую ей.
start
Прежде всего необходимо убедиться, что все службы, от которых зависит нормальная работа, запущены. Если какие-либо необходимые службы выдают ошибку при запуске, будет выполнен выход и выведено соответствующее сообщение; если же всё благополучно, вызывается функция запуска, если она существует.
stop
Прежде всего необходимо убедиться, что все службы, которые зависят от текущих операций, остановлены. Если какие-либо из этих служб выдают ошибку при остановке, будет выполнен выход и выведено соответствующее сообщение; если же всё благополучно, вызывается функция остановки, если она существует.
restart
Останавливает, а затем вновь запускает службу, вместе с зависимыми от нее.
status
Отображает текущее состояние службы. Будет возвращен соответствующий ему код, за исключением состояния "запущено" (started), при котором возвращается 0, для соответствия стандартному поведению команд.
zap
Устанавливает состояние службы "остановлено" (stopped) и удаляет все сохраненные данные о ней.
Следующие опции определяют параметры запуска службы:
-d , -debug
Включить xtrace в оболочке для отладки.
-D , -nodeps
Полностью игнорировать информацию о зависимостях, предоставляемую службой.
-s , -ifstarted
Выполнить команду, только если служба была запущена.
-q , -quiet
Отключить весь информационный вывод, генерируемый службой. Это не влияет на вывод любых других команд, не связанных с OpenRC.
-v , -verbose
Показывать дополнительный информационный вывод, генерируемый службой.
-Z , -dry-run
Показать, какие службы будут остановлены и/или запущены, но не останавливать / не запускать их.
Следующие переменные определяют сценарий службы:
extra_commands
Перечень дополнительных команд, определяемых службой, через пробел.
extra_started_commands
Перечень дополнительных команд, определяемых службой, через пробел. Работает только в том случае, если служба уже запущена.
extra_stopped_commands
Перечень дополнительных команд, определяемых службой, через пробел. Работает только в том случае, если служба уже остановлена.
description
Строка описания службы.
description_$command
Строка, описывающая дополнительную команду.
start_stop_daemon_args
Список аргументов, передаваемых start-stop-daemon'у при запуске службы.
command
Демон, обеспечивающий запуск и остановку посредством start-stop-daemon, если функция запуска-остановки не определена службой.
command_args
Список аргументов, передаваемых демону при запуске.
pidfile
Файл идентификатора процесса, используемый предыдущей командой.
name
Имя, используемое предыдущей командой.
retry
Количество попыток, которые будут предприняты при остановке службы. Это может быть как ожидание в секундах, так и многократные пары сигнал/ожидание (аналогично SIGTERM/5).
ЗАВИСИМОСТИ¶
Чтобы runscript запускался и останавливался в нужный момент по отношению к другим службам, вы должны определить функцию зависимости. Поскольку это функция, depend допускает самую тонкую настройку (см. пример ниже). Перечислим здесь функции, которые могут выступать в качестве функции зависимости. Вы просто передаете им имена служб, которые следует добавить к данному типу зависимости, а для удаления какой-либо службы сопровождаете ее префиксом !.
need
Служба не будет запускаться до запуска необходимых служб и не прекратит работу, пока службы, которым она необходима, не будут остановлены.
use
Служба попытается запустить другие используемые службы, добавленные на уровень запуска.
after
Служба будет запущена после данных служб и остановлена перед их остановкой.
before
Служба будет запущена перед запуском данных служб и остановлена после их остановки.
provide
Обеспечить данную виртуальную службу. Например, named обеспечивает dns.
config
Необходимо заново вычислить зависимости, поскольку файлы изменились.
keyword
Пометить службу ключевым словом. На данный момент поддерживаются следующие ключевые слова:
-shutdown
Не останавливать службу при выходе из системы. Как правило, оставшиеся демоны могут получать сигнал SIGTERM непосредственно перед конечным закрытием. Это ключевое слово обычно имеют службы, обеспечивающие работу в сети, такие как сценарии запуска network и dhcpcd.
-stop
Не останавливать службу при переходе на следующий уровень запуска, даже если его нет. Для выхода из системы.
-timeout
Другие службы должны ожидать вплоть до запуска службы. Используйте данное ключевое слово, если запуск службы может занять более минуты.
-jail
При виртуализации полностью исключать службу из зависимостей. Ее можно будет запустить, вызвав напрямую. Настройка через переменную rc_sys в файле /etc/rc.conf
-lxc
Аналогично -jail, но для виртуализации на уровне операционной системы (LXC, Linux Resource Containers).
-openvz
Аналогично -jail, но для систем OpenVZ.
-prefix
Аналогично -jail, но для систем Prefix.
-uml
Аналогично -jail, но для систем UML.
-vserver
Аналогично -jail, но для систем VServer.
-xen0
Аналогично -jail, но для систем Xen DOM0.
-xenu
Аналогично -jail, но для систем Xen DOMU.
О том, как переопределять зависимости с помощью конфигурационных файлов, см. раздел ФАЙЛЫ.
ВСТРОЕННЫЕ ФУНКЦИИ¶
runscript определяет некоторые встроенные функции, к которым вы можете обращаться из ваших служебных сценариев:
einfo [строка ]
Выводит зеленый астериск перед строкой.
ewarn [строка ]
Выводит желтый астериск перед строкой.
eerror [строка ]
Выводит красный астериск перед строкой.
ebegin [строка ]
Аналогично einfo, но с многоточием в конце.
eend возвращаемая_величина [строка ]
Если возвращаемая_величина не равна 0, выводит строку с eerror и !! в квадратных скобках в конце. Иначе выводить ok в квадратных скобках в конце строки. Возвращается значение возвращаемой_величины.
ewend возвращаемая_величина [строка ]
Аналогично eend, но вместо eerror использовать ewarn.
Перечисленные команды могут иметь префикс v: в этом случае они будут действовать, только если переменная окружения EINFO_VERBOSE имеет значение true.
ewaitfile время файл1 файл2 ...
Ожидать время в секундах, пока не будут перебраны все файлы. Если все файлы существуют, возвращает 0, иначе значение, отличное от единицы. Если значение времени меньше 1, ожидание будет бесконечным.
is_newer_than файл1 файл2 ...
Если файл1 новее файла2, возвращает 0, иначе 1. Если файл2 - каталог, проверяет также его содержимое.
is_older_than файл1 файл2 ...
Если файл1 новее файла2, возвращает 0, иначе 1. Если файл2 - каталог, проверяет также его содержимое.
service_set_value значение_имени
Сохраняет значение_имени для дальнейшего восстановления. Когда служба прекратит свою работу, сохраненные значения будут утрачены.
service_get_value имя
Возвращает сохраненное значение под именем.
service_started [служба ]
Если служба запущена, возвращает 0, иначе 1.
service_starting [служба ]
Если служба запускается, возвращает 0, иначе 1.
service_inactive [служба ]
Если служба неактивна, возвращает 0, иначе 1.
service_stopping [служба ]
Если служба прекращает свою работу, возвращает 0, иначе 1.
service_stopped [служба ]
Если служба остановлена, возвращает 0, иначе 1.
service_coldplugged [служба ]
При холодном запуске службы возвращает 0, иначе 1.
service_wasinactive [служба ]
Если служба была неактивна, возвращает 0, иначе 1.
service_started_daemon [служба ] демон [индекс ]
Если служба запустила демон через start-stop-daemon, возвращает 0, иначе 1. Если был указан индекс, это должен быть pid демона, запущенного службой.
mark_service_started [служба ]
Пометить службу как запущенную.
mark_service_starting [служба ]
Пометить службу как начинающую работу.
mark_service_inactive [служба ]
Пометить службу как неактивную.
mark_service_stopping [служба ]
Пометить службу как завершающую работу.
mark_service_stopped [служба ]
Пометить службу как остановленную.
mark_service_coldplugged [служба ]
Пометить службу как службу с холодной загрузкой.
mark_service_wasinactive [служба ]
Пометить службу как неактивную.
checkpath
[-d , -directory ] [-f , -file ] [-m , -mode режим ] [-o , owner владелец ] путь ...
Проверяет существование пути, его типа, его владельца, режимы доступа. Если при проверке обнаруживается ошибка, путь будет исправлен.
yesno значение
Если значение соответствует YES, TRUE, ON или 1, возвращает 0 независимо от регистра, иначе возвращает 1.
ОКРУЖЕНИЕ¶
runscript присваивает значения следующим переменным окружения, которые можно использовать в сценариях служб:
RC_SVCNAME
Имя службы.
RC_RUNLEVEL
Текущий уровень запуска, на котором находится rc.
RC_BOOTLEVEL
Выбран загрузочный уровень запуска. По умолчанию - boot.
RC_DEFAULTLEVEL
Выбран основной уровень запуска. По умолчанию - default.
RC_SYS
Специальная переменная для дополнительного описания системы. Может принимать значения OPENVZ, XENU, XEN0, UML и VSERVER.
RC_UNAME
Результат выполнения команды `uname -s`.
ФАЙЛЫ¶
Файлы конфигурации, связанные с расположением службы. Если уже существует файл, оканчивающийся на .${RC_RUNLEVEL}, будет использован он.
../conf.d/${RC_SVCNAME%%.*}
Множественный конфигурационный файл. Например: если ${RC_SVCNAME} - net.eth1, обращаться к ../conf.d/net.
../conf.d/${RC_SVCNAME}
Конфигурационный файл службы.
/etc/rc.conf
Конфигурационный файл хоста.
За исключением /etc/rc.conf, конфигурационные файлы могут также переопределять зависимости служб с помощью переменных. Просто добавьте к зависимости префикс rc_. Примеры:
# В то время как большинство служб не требуют определенного интерфейса, наша # конфигурация openvpn в таковом нуждается, а именно в bge0. rc_need="net.bge0" # В файле /etc/rc.conf пропишем rc_openvpn_need="net.bge0" # Службы не должны зависеть от интерфейса tap1 для сетевой работы, # но нам необходимо добавить net.tap1 к уровню запуска default. rc_provide="!net" # В файле /etc/conf.d/net пропишем rc_provide_tap1="!net" # В файле /etc/rc.conf пропишем rc_net_tap1_provide="!net" # Ключевые слова можно использовать с отрицанием. Это особенно удобно для пользователей prefix, # тестирующих OpenRC. rc_keyword="!noprefix"
ПРИМЕРЫ¶
Ниже приводится пример сценария службы для foo.
#!/sbin/runscript command=/usr/bin/foo command_args="${foo_args} --bar" pidfile=/var/run/foo.pid name="FooBar Daemon" description="FooBar is a daemon that eats and drinks" extra_commands="show" extra_started_commands="drink eat" description_drink="Opens mouth and reflexively swallows" description_eat="Chews food in mouth" description_show="Shows what's in the tummy" _need_dbus() { grep -q dbus /etc/foo/plugins } depend() { # Мы сохраняем файл идентификатора процесса и пишем в каталог /var/cache, поэтому нам потребуется localmount: need localmount # Мы можем использовать сеть, но это не обязательно: use net # Служба должна следовать за bootmisc, чтобы каталог /var/run инициализировался до того, # как мы поместим туда файл идентификатора процесса: after bootmisc # Foo может использовать демон dbus. # Но если бы добавим dbus, пока foo работает, # и потом остановим dbus, нам не нужно останавливать foo, поскольку foo не использовала dbus: config /etc/foo/plugins local _need= if service_started; then _need=`service_get_value need` else if _need_dbus; then _need="${_need} dbus" fi fi need ${_need} } start_pre() { # Убедимся, что наши каталоги не содержат ошибок: checkpath --dir --owner foo:foo --mode 0664 \ /var/run/foo /var/cache/foo } start_post() { # Сохраним необходимую службу: if _need_dbus; then service_set_value need dbus fi } stop_post() { # Удалим мусор: rm -rf /var/cache/foo/* } drink() { ebegin "Starting to drink" ${command} --drink beer eend $? "Failed to drink any beer :(" } eat() { local result=0 retval= ate= food= ebegin "Starting to eat" if yesno "${foo_diet}"; then eend 1 "We are on a diet!" return 1 fi for food in /usr/share/food/*; do veinfo "Eating `basename ${food}`" ${command} --eat ${food} retval=$? : $((${result} += ${retval})) [ ${retval} = 0 ] && ate="${ate} `basename ${food}`" done if eend ${result} "Failed to eat all the food"; then service_set_value ate "${ate}" fi } show() { einfo "Foo has eaten: `service_get_value ate`" }
ОШИБКИ¶
По причинам, связанным со способом загрузки конфигурационных файлов и необходимостью обрабатывать несколько служебных каталогов, вы можете использовать в каталогах служб только символические ссылки на другие службы из того же каталога. Вы не можете создавать символическую ссылку, указывающую на службу из другого каталога, даже если другой служебный каталог.
is_older_than должна бы возвращать 0 при успешной отработке, однако в этом случае она возвращает 1, для совместимости с базовым набором (baselayout) Gentoo. Мы рекомендуем пользователям использовать функцию is_newer_, которая работает привычным образом.
СМ. ТАКЖЕ¶
einfo(3), rc(8), rc-status(8), rc-update(8), rc_plugin_hook(3), sh(1p), start-stop-daemon(8), uname(1)
АВТОРЫ¶
- Roy Marples <roy@marples.name>
ПЕРЕВОД¶
- Елена Гаврилова <e.vl.gavrilova@yandex.ru>