Red Hatでプログラムをサービスとしてインストールする必要があります。自身の背景、PIDファイルの管理、独自のログの管理は行いません。実行され、STDOUTおよびSTDERRに出力されます。
ガイドとして標準のinitスクリプトを使用して、以下を開発しました。
#!/bin/bash
#
# /etc/rc.d/init.d/someprog
#
# Starts the someprog daemon
#
# chkconfig: 345 80 20
# description: the someprog daemon
# processname: someprog
# config: /etc/someprog.conf
# Source function library.
. /etc/rc.d/init.d/functions
prog="someprog"
exec="/usr/local/bin/$prog"
[ -e "/etc/sysconfig/$prog" ] && . "/etc/sysconfig/$prog"
lockfile="/var/lock/subsys/$prog"
RETVAL=0
check() {
[ `id -u` = 0 ] || exit 4
test -x "$exec" || exit 5
}
start() {
check
if [ ! -f "$lockfile" ]; then
echo -n $"Starting $prog: "
daemon --user someproguser "$exec"
RETVAL=$?
[ $RETVAL -eq 0 ] && touch "$lockfile"
echo
fi
return $RETVAL
}
stop() {
check
echo -n $"Stopping $prog: "
killproc "exec"
RETVAL=$?
[ $RETVAL -eq 0 ] && rm -f "$lockfile"
echo
return $RETVAL
}
restart() {
stop
start
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
restart
;;
status)
status "$prog"
RETVAL=$?
;;
*)
echo $"Usage: $0 {start|stop|restart|status}"
RETVAL=2
esac
exit $RETVAL
/etc/init.dにある既存のスクリプトの一部をコピーして貼り付け、修正するのが私の間違いだったのかもしれません。いずれにしても、結果のサービスは奇妙な動作をします:
service someprog start
で開始すると、プログラムがターミナルに出力され、コマンドが完了しません。service someprog status
を実行すると、実行中と表示され、そのPIDが一覧表示されます。 ps
で確認できるので、実行中です。service someprog stop
を実行すると停止しません。 ps
を使用して、まだ実行中であることを確認できます。someprog
がバックグラウンドに送信され、サービスとして管理されるようにするには、何を変更する必要がありますか?
編集:私は今、いくつかの関連する質問を見つけましたが、どちらも「他のことをする」以外の実際の答えはありません:
編集:ダブルフォークに関するこの答えは私の問題を解決したかもしれませんが、今私のプログラム自体はダブルフォークであり、それは機能します: https://stackoverflow.com/a/9646251/898699
daemon
関数はアプリケーションをバックグラウンドで実行しないため、コマンドは「完了しません」。次のように、daemon
コマンドの最後に&
を追加する必要があります。
daemon --user someproguser $exec &
someprog
がSIGHUP
を処理しない場合は、Nohup
を指定してコマンドを実行し、プロセスがSIGHUP
を受信しないようにする必要があります。親シェルが終了すると終了します。これは次のようになります。
daemon --user someproguser "Nohup $exec" &
stop
関数では、killproc "exec"
はプログラムを停止するために何も実行していません。それはそう読むべきです:
killproc $exec
killproc
を正しく停止するには、アプリケーションへのフルパスが必要です。過去にkillproc
で問題が発生したため、someprog
のPIDを書き込むPIDFILEのPIDを次のように削除することもできます。
cat $pidfile | xargs kill
次のようにPIDFILEを書き込むことができます。
ps aux | grep $exec | grep -v grep | tr -s " " | cut -d " " -f2 > $pidfile
ここで、$pidfile
は/var/run/someprog.pid
を指します。
stop
関数で[OK]または[FAILED]が必要な場合は、/etc/rc.d/init.d/functions
のsuccess
およびfailure
関数を使用する必要があります。 start
は適切なものを呼び出すため、daemon
関数ではこれらは必要ありません。
スペースを含む文字列を囲む引用符も必要です。それはスタイルの選択ですが、それはあなた次第です。
これらの変更はすべて次のようになります。
#!/bin/bash
#
# /etc/rc.d/init.d/someprog
#
# Starts the someprog daemon
#
# chkconfig: 345 80 20
# description: the someprog daemon
# processname: someprog
# config: /etc/someprog.conf
# Source function library.
. /etc/rc.d/init.d/functions
prog=someprog
exec=/usr/local/bin/$prog
[ -e /etc/sysconfig/$prog ] && . /etc/sysconfig/$prog
lockfile=/var/lock/subsys/$prog
pidfile=/var/run/$prog
RETVAL=0
check() {
[ `id -u` = 0 ] || exit 4
test -x $exec || exit 5
}
start() {
check
if [ ! -f $lockfile ]; then
echo -n $"Starting $prog: "
daemon --user someproguser "Nohup $exec" &
RETVAL=$?
if [ $RETVAL -eq 0 ]; then
touch $lockfile
ps aux | grep $exec | grep -v grep | tr -s " " | cut -d " " -f2 > $pidfile
fi
echo
fi
return $RETVAL
}
stop() {
check
echo -n $"Stopping $prog: "
killproc $exec && cat $pidfile | kill
RETVAL=$?
if [ $RETVAL -eq 0 ]; then
rm -f $lockfile
rm -f $pidfile
success; echo
else
failure; echo
fi
echo
return $RETVAL
}
restart() {
stop
start
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
restart
;;
status)
status $prog
RETVAL=$?
;;
*)
echo $"Usage: $0 {start|stop|restart|status}"
RETVAL=2
esac
exit $RETVAL