我需要在Red Hat上安装一个程序作为服务。 它不会后台自己,pipe理其PID文件,或pipe理自己的日志。 它只是运行并打印到STDOUT和STDERR。
使用标准的初始化脚本作为指南,我开发了以下内容:
#!/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 start程序打印到terminal,命令没有完成。 service someprog status它说它正在运行并列出其PID。 我可以看到它在ps所以它正在运行。 service someprog stop它无法停止。 我可以validation它仍然运行与ps 。 我需要改变什么,以便将someprog程序发送到后台并作为服务进行pipe理?
编辑:我现在发现了一些相关的问题,除了“做别的事情”之外,他们都没有真正的答案:
编辑:这个双分叉的答案可能已经解决了我的问题,但现在我的程序本身双叉和工程: https : //stackoverflow.com/a/9646251/898699
该命令“不完整”,因为daemonfunction不会在daemon运行您的应用程序。 你需要在你的daemon命令的末尾添加一个& ,如下所示:
daemon --user someproguser $exec &
如果someprog不能处理SIGHUP ,则应该使用nohup运行该命令,以确保您的进程不会收到SIGHUP ,这会告诉您的进程在父shell退出时退出。 这看起来像这样:
daemon --user someproguser "nohup $exec" &
在你的stop函数中, killproc "exec"没有做任何事情来停止你的程序。 它应该这样读:
killproc $exec
killproc需要您的应用程序的完整path来正确地停止它。 我在过去使用killproc时遇到了一些麻烦,所以你也可以在PIDFILE中杀掉PID,你应该用下面这样的东西来写someprog 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为你调用适当的。
你也只需要用空格的string引号。 不过这是一种风格select,所以取决于你。
所有这些变化看起来像这样:
#!/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
如果这是你的程序,请把它写成适当的守护进程。 特别是如果它的重新分配。 🙂
你可以尝试monit 。 或者,也许像runit或daemontools。 那些可能没有现成的软件包。 Daemontools来自DJB,如果这影响你的决定(在任何方向)。
我已经做了更多的研究,看来答案是“你不能这样做”。 要运行的程序必须正确地进行自身的守护程序:fork和分离它的标准文件句柄,从terminal分离,并开始一个新的会话。
编辑:显然我错了 – 双分叉将工作。 https://stackoverflow.com/a/9646251/898699