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)

АВТОРЫ

ПЕРЕВОД

 
 

Спасибо!