FreeBSD において,デーモンのような,システム開始時に自動的に起動し,シャットダウン時に安全に停止させたいプログラムの起動・停止スクリプトは,
私も弊サイトのサービス — misimaserver(旧字・旧仮名遣い表記変換サーバ),misimakansiserver(漢詩平仄音韻分析サーバ),Pushkin Lemmatized Concordance(プーシキン全集見出し語コンコーダンス)— について,/usr/
今日は rc.d スクリプトの基本的な書き方について備忘録を残しておく。私の環境は FreeBSD 9.2-RELEASE であるが,かなり前のバージョンでも通用するかと思う。ここでの記述はマニュアル(man rc.d,man rc.subr)のほか,多くを Practical rc.d scripting in BSD に負うている。
rc.d スクリプト例
rc.d スクリプトのシンプルな例を以下に示す。システム開始時に “Now, begin rcsample” を,システム停止時に “Wow, I'm tired.” をシスログに出力するだけの他愛ないものである。
#!/bin/sh # -*- coding: utf-8; mode: shell-script; -*- # FreeBSD /usr/local/etc/rc.d script sample # insert `rcsample_enable="YES"' in /etc/rc.conf # 2015(c) isao yasuda, All Rights Reserved. # PROVIDE: rcsample # REQUIRE: sshd # BEFORE: apace22 # KEYWORD: nojail shutdown . /etc/rc.subr name="rcsample" rcvar="${name}_enable" start_cmd="${name}_start" stop_cmd="${name}_stop" load_rc_config $name : ${rcsample_enable:="NO"} rcsample_start () { /bin/echo "Now, begin rcsample." | /usr/bin/logger -t rcsample } rcsample_stop () { /bin/echo "Wow, I'm tired." | /usr/bin/logger -t rcsample } run_rc_command "$1"
これを rcsample というファイル名で,/usr/
rcsample_enable="YES"
さて,これで準備が完了である。コマンドラインから sudo service rcsample start を投入すると,
Jun 14 00:48:06 beatrice rcsample: Now, begin rcsample.
と,同様に sudo service rcsample stop を投入すると,
Jun 14 00:48:12 beatrice rcsample: Wow, I'm tired.
と,シスログに書き出されているはずである。
rc.d スクリプトの書き方の概略
rc.d スクリプトのポイントについて簡単に説明する。(line xx) の xx は,上記 Bourne Shell スクリプト例の行番号を示している。
- . /etc/rc.subr(line 12)/etc/rc.subr には rc.d スクリプトで用いる変数や関数が定義されており,スクリプトの冒頭で . コマンドを使って読み込んでおく。
- name="rcsample"(line 14)これは必須の変数定義である。スクリプト名と同じ値をセットしておく。
/etc/ rc. subr の各種関数・変数を使用する前にこれを記述しなければならない。 - rcvar="${name}_enable"(line 15)rcvar 変数は,実行の ON/OFF のスイッチとなる変数を定義する。例の指定は,
/etc/ rc. conf 中に rcsample_ enable= "YES" という記述があると,このスクリプトを実行の対象にするということを設定する。 - start_cmd="${name}_start"(line 17)
- stop_cmd="${name}_stop"(line 18)開始時,終了時に呼び出す関数名の設定である。通常は start_cmd,
stop_cmd に対し,それぞれ関数名 ${name}_ start, ${name}_ stop を指定し,スクリプト内でこれらの関数の実体(実行内容)を記述する(line 23, 27)。停止時に何もする必要がなければ stop_ cmd= ":" と書いておけばよい。その場合,もちろん,関数本体の記述は不要である(“:” は,リターンコード 0 を返すだけの,「何もしない」という Bourne Shell コマンドである)。 もしサービスが一般的デーモン構造を有するものなら,line 17, 18 を command="/path/to/${name}"(/path/ to/ はプログラム ${name} が実際に格納されているディレクトリ・パス)と簡易に書くことが出来る。この場合, rc.d スクリプトの引数として, start, stop のほか, restart, status (状態確認), poll (ポーリング)といったデーモンに対する一般的オペレーションが想定されており,必要に応じて扱う関数(たとえば, status_ cmd に対して ${name}_ status)を定義することが出来る。 - load_rc_config $name(line 20)
- : ${rcsample_enable:="NO"}(line 21)これにより /etc/
rc. conf の変数定義が読み込まれ,${rcsample_ enable} に値がセットされていればそのまま,セットされていなければ “NO” が ${rcsample_ enable} に設定される。この記述により, /etc/ rc. conf で rcsample_ enable= "YES" が設定されていなければ,次に説明する run_ rc_ command は実行されない仕組みになっている。 - run_rc_command "$1"(line 31)これにより,スクリプトの第一引数が $1 に渡って,
${name}_$1 関数が実行される。開始時には引数として start が与えられ, rcsample_ start 関数が実行されることになる。通常の rc.d スクリプトでは末尾に記述しておく。 run_ rc_ command は /etc/ rc. subr で定義された関数である。
実行順序制御条件指定
プログラムによっては,その動作の前提となるサービスがあったり,あるサービスに先立って実行される必要があったりする事情がある。rc.d スクリプトでは,この実行順序制御条件の指定が可能である。上記スクリプト例中のコメントとして記述された # PROVIDE:,
- # PROVIDE: rcsample(line 7)rcsample の名前を条件指定に使用できるようにする宣言である。これにより,他の rc.d スクリプトから,後述の REQUIRE,
BEFORE で指定されることが出来るようになる。 - # REQUIRE: sshd(line 8)この例では,
sshd を PROVIDE するスクリプトよりも後に本スクリプトを実行する指定である。右辺には LOGIN(sshd 等のログインサービス系のサービス), DAEMON(lpd 等の古典的デーモン系のサービス)のような一般的指定が可能である。 - # BEFORE: apache22(line 9)この例では,apache22 を PROVIDE するスクリプトよりも前に本スクリプトを実行する指定である。右辺には LOGIN(sshd 等のログインサービス系のサービス),
DAEMON(lpd 等の古典的デーモン系のサービス)のような一般的指定が可能である。 - # KEYWORD: nojail shutdown(line 10)例にある shutdown キーワードは,システムがシャットダウンする前に停止される必要があることを明示する。
rcsample 例のように指定すると,sshd よりも後,apache22 よりも前に rcsample スクリプトが実行される。これは service -e もしくは rcorder /usr/
# service -e /etc/rc.d/hostid /etc/rc.d/hostid_save /etc/rc.d/cleanvar /etc/rc.d/ip6addrctl /etc/rc.d/devd /etc/rc.d/newsyslog /etc/rc.d/syslogd /usr/local/etc/rc.d/slapd /etc/rc.d/rpcbind /etc/rc.d/dmesg /etc/rc.d/nfsd /etc/rc.d/virecover /etc/rc.d/motd /etc/rc.d/ntpd /usr/local/etc/rc.d/svnserve /etc/rc.d/sshd /usr/local/etc/rc.d/misimamfs /usr/local/etc/rc.d/tomcat7ctl /usr/local/etc/rc.d/saslauthd /usr/local/etc/rc.d/sa-spamd /usr/local/etc/rc.d/rcsample /usr/local/etc/rc.d/pushkin_concordance /usr/local/etc/rc.d/mysql-server /usr/local/etc/rc.d/amavisd /usr/local/etc/rc.d/clamav-clamd /usr/local/etc/rc.d/clamav-freshclam /usr/local/etc/rc.d/imapd /usr/local/etc/rc.d/postfix /usr/local/etc/rc.d/misimakansid /usr/local/etc/rc.d/misimad /usr/local/etc/rc.d/ddclient /usr/local/etc/rc.d/dbus /usr/local/etc/rc.d/apache22 /etc/rc.d/cron /etc/rc.d/mixer /etc/rc.d/inetd /etc/rc.d/gptboot /etc/rc.d/bgfsck #
以上の要素を使うことで,実用的な rc.d スクリプトを書くことが出来る。もちろん,
参考文献
rc.d スクリプトの参考文献というわけではないが,ちょこちょこナイスな Tips が得られる BSD ユーザ必携の文献をあげておきます。