/etc/init.d
下面是控制守护进程的脚本的一部分。完整的 init.script 位于http://pastebin.com/02G5tpgH
case "$1" in
start)
printf "%-50s" "Starting $DAEMON_NAME..."
cd $DIR
[ -d $LOGPATH ] || mkdir $LOGPATH
[ -f $LOGFILE ] || su $DAEMON_USER -c 'touch $LOGFILE'
PID=`$PYTHON $DAEMON $DAEMON_OPTS > $LOGFILE 2>&1 & echo $!`
#echo "Saving PID" $PID " to " $PIDFILE
if [ -z $PID ]; then
printf "%s\n" "Fail"
else
echo $PID > $PIDFILE
printf "%s\n" "Ok"
fi
;;
status)
printf "%-50s" "Checking $DAEMON_NAME..."
if [ -f $PIDFILE ]; then
PID=`cat $PIDFILE`
if [ -z "`ps axf | grep ${PID} | grep -v grep`" ]; then
printf "%s\n" "Process dead but pidfile exists"
else
echo "Running"
fi
else
printf "%s\n" "Service not running"
fi
;;
stop)
printf "%-50s" "Stopping $DAEMONNAME"
PID=`cat $PIDFILE`
cd $DIR
if [ -f $PIDFILE ]; then
kill -HUP $PID
printf "%s\n" "Ok"
rm -f $PIDFILE
else
printf "%s\n" "pidfile not found"
fi
;;
restart)
$0 stop
$0 start
;;
*)
echo "Usage: $0 {status|start|stop|restart}"
exit 1
esac
我使用 capistrano2 来部署/更新此应用程序。因此,在部署之前,我有一个任务来停止应用程序/服务,然后另一个任务来启动服务部署后任务。在此过程中,服务从未通过 capistrano 任务成功启动。它抛出错误。
进程死掉但 pidfile 存在
手动停止和启动无法重现此问题。所以看起来像是某种守护程序问题,通过脚本调用时服务不会启动
编辑:
根据迄今为止的证据,看起来剧本的这一部分失败了。
case "$1" in
start)
printf "%-50s" "Starting $DAEMON_NAME..."
cd $DIR
[ -d $LOGPATH ] || mkdir $LOGPATH
[ -f $LOGFILE ] || su $DAEMON_USER -c 'touch $LOGFILE'
PID=`$PYTHON $DAEMON $DAEMON_OPTS > $LOGFILE 2>&1 & echo $!`
if [ -z $PID ]; then
printf "%s\n" "Fail"
else
echo $PID > $PIDFILE
printf "%s\n" "Ok"
fi
;;
答案1
这很奇怪。如果这是您的脚本,那么它不是产生错误/失败原因的脚本,或者 Capistrano 正在将标准输出发送到终端之外的其他地方。
您提供的第一行代码是:cat: /var/run/daemon_name.pid: No such file or directory
。唯一养猫的地方是status
和stop
部分。因此,您应该看到Checking...
orStopping...
输出,但您没有看到。至少,你不表现出来。
val0x00ff 在文件顶部使用 set -x 的建议很好。如果输出太多,请尝试以下操作:
我会在您的案例陈述中添加更多信息,如下所示:
echo "Got here" 1>&2
这会将消息发送到 stderr,您可以看到发生了什么(显然,来自 cat 的错误将发送到 stderr)。
PID= `cat $PIDFILE`
在上面代码中的每个语句前面,执行以下操作:
{ date; hostname; ls -l /var/run; } 1>&2
确保一切看起来都正确。
更正变量名和反引号虽然可能会使 bash 代码更加标准或最新,但这并不是问题的根源。
答案2
原因并不是卡皮斯特拉诺本身。这是由于 capistrano 生成的进程在任务结束后退出时被杀死。我们必须修改 init 脚本来解决这个问题。“nohup”用于将守护进程保留在 bg 中,即使在 ssh 会话存在 cap 后也是如此。以下是(启动)init 脚本的修改部分。
case "$1" in
start)
#checking to see if the process is already running, if it is, display a message and exit
if [ -n "`ps aux |grep /opt/mount/xyz/current/src/main.py | grep -v grep`" ]; then
echo "Service is already running, try stopping it first with 'service xyz stop'"
exit
fi
printf "%-50s" "Starting $DAEMON_NAME..."
cd $DIR
[ -d $LOGPATH ] || mkdir $LOGPATH
[ -f $LOGFILE ] || su $DAEMON_USER -c 'touch $LOGFILE'
nohup $PYTHON $DAEMON $DAEMON_OPTS > $LOGFILE 2>&1 &
echo $! > $PIDFILE
sleep 5
;;