我正在启动一个使用创建的 Python 脚本start-stop-daemon
。它在所有情况下都能完美运行,除非我忘记已经启动了它。它会创建一个新进程,但无法自动终止旧进程。
完整脚本如下:
PYTHONPATH=/usr/lib/python2.4
# path to app
APP_PATH=/var/spool/EARS
# path to paster bin
DAEMON=/var/spool/EARS/pymilter_test8.py
# startup args
#DAEMON_OPTS=" serve --log-file <my logfile> --server-name=main production.ini"
# script name
NAME=EARS_milter.sh
# app name
DESC='EARS_milter'
# pylons user
RUN_AS=postfix
PID_FILE=/var/run/milter.pid
############### END EDIT ME ##################
test -x $DAEMON || exit 0
set -e
case "$1" in
start)
echo -n "Starting $DESC: "
start-stop-daemon -d $APP_PATH -c $RUN_AS --start --background --pidfile $PID_FILE --make-pidfile --exec $DAEMON -- $DAEMON_OPTS
echo "$NAME."
;;
stop)
echo -n "Stopping $DESC: "
start-stop-daemon --stop --pidfile $PID_FILE
echo "$NAME."
;;
restart|force-reload)
echo -n "Restarting $DESC: "
start-stop-daemon --stop --pidfile $PID_FILE
sleep 1
start-stop-daemon -d $APP_PATH -c $RUN_AS --start --background --pidfile $PID_FILE --make-pidfile --exec $DAEMON -- $DAEMON_OPTS
echo "$NAME."
;;
*)
N=/etc/init.d/$NAME
echo "Usage: $N {start|stop|restart|force-reload}" >&2
exit 1
;;
esac
exit 0
有办法检查吗?我试过 -S 开关,但目前没有成功。
谢谢。
答案1
$PID_FILE
将仅包含您启动的最新实例的进程 ID,因此只有该实例会被终止。
为解决此问题,您可以采取以下措施:grep 守护进程正在运行的实例的 PID,然后使用 终止它们kill
。
...或者在调用之前检查脚本是否有另一个正在运行的实例start-stop-daemon
。
正在生成和运行的是 Python 解释器,但start-stop-daemon
检查名为的进程pymilter_test8.py
却显然找不到它。
答案2
我最近在使用启动数据库服务器(Crate)时遇到了一个问题start-stop-daemon
。数据库是用一个bash
脚本启动的,然后java
在一个单独的进程中启动。这是一个问题,因为实际的服务器总是列在第二个 PID 下。当我让服务器本身创建 PID 文件时,我发现start-stop-daemon
当我使用参数时,仍然无法识别服务器已在运行--pidfile
。但是,当我使用--startas
而不是--exec
作为启动调用时,它似乎为我解决了问题,start-stop-daemon
能够再次正确管理服务器进程。
您必须至少确保 PID 文件正确,因为像我这样的分叉服务器将使用与启动它的进程不同的运行 PID。在调试时,使用该-t
标志很有帮助,因为您可以手动运行start-stop-daemon
在每种情况下命令并监视它会做什么。
答案3
您可以在 中使用锁定文件/var/lock
。让守护进程在启动之前检查锁定文件,如果锁定文件存在,则失败并显示错误。如果没有失败,它将创建锁定文件。这样两个实例就不能同时运行。
唯一的问题是,如果它崩溃而无法清理混乱,您必须手动删除锁定文件。这不是什么大问题。锁定文件的位置应该在启动失败时创建的错误消息中。
在开始的情况下,你会输入类似这样的内容:
if [ -f /var/lock/filename.lck ]; then
echo "Lock file already present at /var/lock/filename.lck. Aborting"
exit 1
else
touch /var/lock/filename.lck
fi
然后在停止的情况下,是这样的:
if [ -f /var/lock/filename.lck ]; then
rm /var/lock/filename.lck
fi
它涉及超出正常配置编辑部分范围的编辑,但它应该可以工作。