Во время запуска и остановки системы rc.d скрипт
предположительно оперирует над той или иной подсистемой целиком. К примеру, скрипт /etc/rc.d/netif должен запускать и останавливать все сетевые
интерфейсы, описанные в rc.conf(5). Так же
каждая задача должна быть целиком описана одной командой - start или stop. Но между запуском
системы и ее остановкой rc.d должны помогать системному
администратору управлять запущенными процессами, и зачастую для этого необходимо больше
гибкости. Например, администратор может сконфигурировать новый интерфейс в rc.conf(5) и ему
понадобиться запустить только этот интерфейс, не затрагивая все остальные. В следующий
раз, администратору может понадобиться остановить этот единственный интерфейс. Для этого
можно передавать дополнительные опции для скрипта, такие как название интерфейса, в виде
дополнительных аргументов командной строки.
К счастью, rc.subr(8) позволяет передать скрипту любое количество аргументов (в пределах системных ограничений). Поэтому, можно обойтись минимальными изменениями скрипта.
Как rc.subr(8) может
получить доступ к аргументам командной строки? Передать их непосредственно внутри скрипта
функции run_rc_command невозможно, так как функции sh(1) не имеют доступа
к позиционным параметрам вызывающего их объекта. Кроме того, в rc.d скриптах считается хорошим тоном, когда скрипт сам определяет
какие аргументы должны быть переданы его методам.
В rc.subr(8)
используется следующее решение: функции run_rc_command
передаются все аргументы командной строки, при этом подразумевается, что первым из этих
аргументов является имя запускаемого метода - start, stop и т.д. Эти аргументы сдвигаются внутри функции run_rc_command c помощью оператора sh(1) shift. Таким образом, переменная $2 в
изначальной командной строке передается методу как $1, и так
далее.
So the approach adopted by rc.subr(8) is as follows:
Хорошо проиллюстрировать это нам поможет следующий пример. Давайте изменим наш первый простейший скрипт так, чтобы его сообщения зависели от дополнительных аргументов. Итак:
#!/bin/sh
. /etc/rc.subr
name="dummy"
start_cmd="${name}_start"
stop_cmd=":"
kiss_cmd="${name}_kiss"
extra_commands="kiss"
dummy_start()
{
if [ $# -gt 0 ]; then
echo "Greeting message: $*"
else
echo "Nothing started."
fi
}
dummy_kiss()
{
echo -n "A ghost gives you a kiss"
if [ $# -gt 0 ]; then
echo -n " and whispers: $*"
fi
case "$*" in
*[.!?])
echo
;;
*)
echo .
;;
esac
}
load_rc_config $name
run_rc_command "$@"
Какие значимые изменения были сделаны в этом файле?

start
будут переданы как аргументы соответствующему методу. Мы можем использовать их любым
способом в соответствии с поставленной задачей и в меру наших навыков и фантазии. В
настоящем примере мы просто передаем их все команде echo(1) как одну
строку в переменной $* внутри двойных кавычек. Вот пример как
может быть вызван такой скрипт:# /etc/rc.d/dummy start Nothing started. # /etc/rc.d/dummy start Hello world! Greeting message: Hello world!

kiss, и он будет
иметь те же возможности, что и метод start:
# /etc/rc.d/dummy kiss A ghost gives you a kiss. # /etc/rc.d/dummy kiss Once I was Etaoin Shrdlu... A ghost gives you a kiss and whispers: Once I was Etaoin Shrdlu...

run_rc_command.Important: Программисты на языке sh(1) обязаны понимать тонкую разницу между специальными переменными $* и $@ и тем, как они передают позиционные параметры. Для более тщательного изучения этого вопроса ознакомьтесь с очень подробной страница справочника sh(1). Не используйте эти переменные, если вы не понимаете их действие, поскольку их неправильное использование может сделать ваш скрипт неправильно работающим и небезопасным.
Note: В настоящее время функция
run_rc_commandимеет ошибку, которая может привести терять к потере разделителей между аргументами. Поэтому, аргументы, в которых присутствует пробел могут обрабатываться некорректно. Появление этой ошибки может быть спровоцировано неправильным использованием переменной $*.
Этот, и другие документы, могут быть скачаны с ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/.
По вопросам, связанным с FreeBSD, прочитайте документацию прежде чем писать в <questions@FreeBSD.org>.
По вопросам, связанным с этой документацией, пишите <doc@FreeBSD.org>.
По вопросам, связанным с русским переводом документации, пишите в рассылку <frdp@FreeBSD.org.ua>.
Информация по подписке на эту рассылку находится на сайте проекта перевода.