スクリプト をサービス登録するテンプレート[init.d編]


🐒   この記事は fhd@github 氏のスクリプトをサービス登録するためのテンプレート「init-script-templateの「README.md」を翻訳したものです。ライセンスはオリジナルと同じ MIT ライセンスです。

「お前もサービスにしてやろうか」俺様スクリプトのデーモン化

このテンプレートを使うと:

  • 任意のスクリプトを Daemonize できます。
    start, stop, restart, status コマンドに対応させつつサービスに登録できます)
  • 自作スクリプト問わずコマンド実行できれば何でもサービス化できます.
  • CentOS6 などの init.d 対応の Linux OS で利用できます。
  • Raspberry Pi(Raspbian Wheezy 以前)などで、いい感じで動いた Node.js アプリを登録するのに便利です。
    • Raspbian Jessy 以降の場合は SystemD を使うことが推奨されています。
  • PHP, Perl, Python だって登録可能です。
  • 同じもので init.d でなく SystemD のテンプレートをお求めの場合はこちら

まずは「コマンドを叩いたら動作する適当な常駐系のスクリプト」が用意できた前提でご覧ください。

ここでいう「常駐系」とは、無限ループなどで永遠と処理を実行するタイプのアプリを言います。例えば、特定ディレクトリを定期的にチェックし、変更があったら cURL などで WebHook1 先の URL を叩いたり、メールを飛ばすなどのアプリを指します。

なお、本記事は Amazon Dash Button をラズパイで遊ぶのに利用した Dasher の中の人が README 内でこっそり教えてくれてた内容を元にしています。また、起動時(ブート時)にサービスを自動起動したい場合Dasher の Wiki が詳しいです。(これも訳した方がいいかしら? 👍10個ついたら訳そうと思います)

🐒  【2019/02/26 追記】
気づいたら 20 いただいちゃってたので記事を作成しました。SystemV 系の init.d だけでなく SystemD のテンプレートも記載してあります。

また、本記事と直接は関係ありませんが、参考文献となった Node.js ベースの Dasher は開発を終了し、代替として Python ベースの「Nekmo/amazon-dash」がお薦めされています。また、Amazon Dash Button も販売が終了したそうです。残念。

▼以下訳


System V init スクリプト・テンプレート

Init スクリプトに、start, stop, restart, status コマンドを提供するシンプルなテンプレートです。

Node.js アプリや、その他の実行可能なスクリプトにも手軽に使えて便利です。

準備

スクリプトのテンプレート/etc/init.d/ にコピーして、わかりやすいファイル名(=サービス名)に変更してください。次にファイルを開き Provides: の項目の後にスクリプト名を入力します。(### BEGIN INIT INFO### END INIT INFO の間にあります)

テンプレート

本記事の元となった Dasher が開発を終了したため、念の為以下にテンプレートのバックアップをおきます。(2019/02/26)

init-script-template.sh
#!/bin/sh
### BEGIN INIT INFO
# Provides:
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Start daemon at boot time
# Description:       Enable service provided by daemon.
### END INIT INFO

dir=""
cmd=""
user=""

name=`basename $0`
pid_file="/var/run/$name.pid"
stdout_log="/var/log/$name.log"
stderr_log="/var/log/$name.err"

get_pid() {
    cat "$pid_file"
}

is_running() {
    [ -f "$pid_file" ] && ps -p `get_pid` > /dev/null 2>&1
}

case "$1" in
    start)
    if is_running; then
        echo "Already started"
    else
        echo "Starting $name"
        cd "$dir"
        if [ -z "$user" ]; then
            sudo $cmd >> "$stdout_log" 2>> "$stderr_log" &
        else
            sudo -u "$user" $cmd >> "$stdout_log" 2>> "$stderr_log" &
        fi
        echo $! > "$pid_file"
        if ! is_running; then
            echo "Unable to start, see $stdout_log and $stderr_log"
            exit 1
        fi
    fi
    ;;
    stop)
    if is_running; then
        echo -n "Stopping $name.."
        kill `get_pid`
        for i in 1 2 3 4 5 6 7 8 9 10
        # for i in `seq 10`
        do
            if ! is_running; then
                break
            fi

            echo -n "."
            sleep 1
        done
        echo

        if is_running; then
            echo "Not stopped; may still be shutting down or shutdown may have failed"
            exit 1
        else
            echo "Stopped"
            if [ -f "$pid_file" ]; then
                rm "$pid_file"
            fi
        fi
    else
        echo "Not running"
    fi
    ;;
    restart)
    $0 stop
    if is_running; then
        echo "Unable to stop, will not attempt to start"
        exit 1
    fi
    $0 start
    ;;
    status)
    if is_running; then
        echo "Running"
    else
        echo "Stopped"
        exit 1
    fi
    ;;
    *)
    echo "Usage: $0 {start|stop|restart|status}"
    exit 1
    ;;
esac

exit 0

続けて以下の3つの項目の値を設定します。

dir
プロセスの作業ディレクトリを指定します
cmd
プロセスを実行するコマンド(いつも入力しているコマンド)
user
コマンドを実行するユーザー(オプション)。実行ユーザーが指定されていない場合は `sudo ...` を通して `root` として実行されます。

設定例

以下は algorithms という Node.js アプリの場合の設定例です。

/etc/init.d/algorithms
...
    dir="/var/apps/algorithms"
    cmd="node server.js"
    user="node"
...

使い方

Start

アプリを開始します。

/etc/init.d/algorithms start

Stop

アプリを停止します。

/etc/init.d/algorithms stop

Restart

アプリを再起動します。(stop→start)

/etc/init.d/algorithms restart

Status

アプリが実行中か確認できます。実行中の場合は Running(戻り値 0 ) 、それら以外の場合は Stopped (戻り値 1 )が表示されます。

/etc/init.d/algorithms status

ログ出力

デフォルトの設定では、標準出力は /var/log/<scriptname>.log に出力され、エラー出力は
/var/log/<scriptname>.err に出力されます。出力先を変更したい場合は stdout_logstderr_log の項目を変更してください。

ライセンス

Copyright (C) 2012-2014 Felix H. Dahlke

これは MIT ライセンスの OSS です。詳細は LICENSE ファイルをご覧ください。


  1. 【WebHook(ウェブフック)とは】何かの条件に反応して指定された URL を叩くこと。トリガーのようなもの。IFTTTが有名。GitHub などではリポジトリに変更があると、登録された URL に JSON データを POST することで WebHook 機能を実装しており、これを利用して CI や Slack 通知などが実現できている。