bash 脚本在主管启动和重启时的不同行为

Different behaviour of bash script on supervisor start and restart

我有 bash 脚本可以做一些事情,(例如:)

[program:long_script]
command=/usr/local/bin/long.sh
autostart=true
autorestart=true
stderr_logfile=/var/log/long.err.log
stdout_logfile=/var/log/long.out.log

并且绑定到supervisor。 我想添加 if check in this script 以确定它是否由以下人员执行:

我想要这样的东西:

if [ executed by start command ]
then
    echo "start"
else
    echo "restart"
fi

但我不知道 if 子句中应该包含什么。 是否可以确定这一点? 如果不是,如何为启动和重启命令实现脚本的不同行为? 请帮忙。

我明白你的问题。但我不知道主管。请检查这个想法是否可行。

实例化一个全局字符串变量并在输入主管命令之前将值赋给该变量。在这里,我将您的每个启动和重新启动命令作为两个 bash 程序。

程序:supervisor_start.sh

#!/bin/bash
echo "Starting.."
supervisor> start long_script
supervisor_started_command="start" # This is the one
echo "Started.."

程序:supervisor_restart.sh

#!/bin/bash
echo "ReStarting.."
supervisor> restart long_script
supervisor_started_command="restart" # This is the one
echo "ReStarted.."

现在您可以看到 "supervisor_started_command" 变量中的内容:)

#!/bin/bash
if [ $supervisor_started_command == "start" ]
then
    echo "start"
elif [ $supervisor_started_command == "restart" ]
    echo "restart"
fi

好吧,我不知道这个想法是否适合你..

在代码中,重启和 stop/start 之间没有电流差异。在 supervisorctl 调用中重新启动:

self.do_stop(arg)
self.do_start(arg)

虽然有一些关于允许不同信号的讨论,但 "restart" 的应用程序中没有状态。主管已经能够向流程发送不同的信号。 (允许对 reload/restart 的更多控制已经 long standing "gap"

这意味着您至少有两个选择,但实现此功能的关键是进程需要在 shutdown

时记录一些状态

选项 1。 最简单的选项是使用 supervisorctl signal <singal> <process> 而不是调用 supervisorctl restart <process> 并在某处记录发送了什么信号,以便在启动时你可以读回最后一个信号。

选项 2。 然而,一个更有趣的解决方案是不要期望任何上游更改,即继续允许使用重启并区分停止、崩溃和重启

在这种情况下,启动和重新启动之间唯一不同的信息是重新启动应该在旧进程关闭和重新启动之间有更短的时间新进程的开始。因此,如果在关机时记录时间戳,那么在启动时,现在和上次关机之间的差异将区分启动和重启

为此,我有一个与您类似的定义,但定义了停止信号:

[program:long_script]
command=/usr/local/bin/long.sh
autostart=true
autorestart=true
stderr_logfile=/var/log/long.err.log
stdout_logfile=/var/log/long.out.log
stopsignal=SIGUSR1

通过将 supervisord 的停止设为特定信号,您可以区分崩溃和正常停止事件,并且不会干扰正常的终止或中断信号

然后作为bash脚本的第一行,我为这个信号设置了一个陷阱:

trap "mkdir -p /var/run/long/; date +%s > /var/run/long/last.stop; exit 0" SIGUSR1

这意味着作为纪元的日期将被记录在文件中/var/run/long/last。每次我们从 supervisord 发送停止时停止

然后作为脚本中紧接的下一行,计算上次停止与现在之间的差异

stopdiff=0
if [ -e /var/run/long/last.stop ]; then
    curtime=$(date +%s)
    stoptime=$(cat /var/run/long/last.stop | grep "[0-9]*")
    if [ -n "${stoptime}" ]; then
            stopdiff=$[ ${curtime} - ${stoptime} ]
    fi
else
    stopdiff=9999
fi

stopdiff 现在将包含停止和开始之间的秒数差异,如果停止文件不存在,则为 9999。

这可以用来决定要做什么:

if [ ${stopdiff} -gt 2 ]; then
    echo "Start detected (${stopdiff} sec difference)"
elif [ ${stopdiff} -ge 0 ]; then
    echo "Restart detected (${stopdiff} sec difference)"
else
    echo "Error detected (${stopdiff} sec difference)"
fi

您必须选择从发送停止到脚本实际开始实际需要多长时间:在这里,我只允许 2 秒,任何更长的时间都被认为是 "start"。如果脚本的关闭需要以特定方式发生,您需要在 trap 语句中稍微复杂一些(而不仅仅是 exit 0

由于崩溃不应该在停止文件中记录任何时间戳,如果您还定期在某个地方记录 运行 时间戳,您应该能够判断启动是由于崩溃引起的。