初始化脚本以ssh会话结束

我们需要在less数几台服务器上运行pt-stalk来关注mySQL,每当服务器重新启动时我都会手动启动它。 一个小小的search引擎出现了一个pt-stalk的初始化脚本 ,它似乎工作得很好。 [我稍微修改过的版本包括在这篇文章的底部]

如何通过ssh来推送脚本和configuration需要很长的时间[长篇故事,请不要问]所以我决定只login到20多台服务器,手动设置一切,一切正常。

几天后,我的同事评论说,他正在收到电子邮件,但我显然不是,而且看起来我把错误的电子邮件放在configuration中。 这一次,我已经想出了如何通过SSH推动改变,并完成了一切:

for server in `cat serverlist.txt`; do ssh -t $server sudo -i service pt-stalk restart done 

这就是pt-stalk停止在每台服务器上工作的地方:

 2013_08_23_11_43_20 Caught signal, exiting 2013_08_23_11_43_20 Exiting because OKTORUN is false 2013_08_23_11_43_20 /usr/bin/pt-stalk exit status 1 2013_08_23_11_43_22 Starting /usr/bin/pt-stalk --function=status --variable=Threads_connected --threshold=100 --match= --cycles=5 --interval=1 --iterations= --run-time=30 --sleep=300 --dest=/var/lib/pt-stalk --prefix= [email protected] --log=/var/log/pt-stalk.log --pid=/var/run/pt-stalk.pid 2013_08_23_11_43_22 Caught signal, exiting 

通过昨天的testing,我发现“捕获信号,退出”意味着它被捕获为HUP / TERM / KILL 。 第一个是从service pt-stalk restart第二个是在ssh会话closures后立即成功启动的。 wat.jpg

如果我只是SSH服务器,inputsudo -i service pt-stalk startrestart我可以注销,它继续愉快。 但是,如果我只是像上面的循环pt-stalk一样向ssh提供一个命令,它就会捕获一个信号并退出。 有时它在退出之前捕获两个信号。

这到底是怎么回事?


我的/etc/init.d/pt-stalk供参考:

 #!/usr/bin/env bash # chkconfig: 2345 20 80 # description: pt-stalk ### BEGIN INIT INFO # Provides: pt-stalk # Required-Start: $network $named $remote_fs $syslog # Required-Stop: $network $named $remote_fs $syslog # Should-Start: pt-stalk # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 ### END INIT INFO PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin DAEMON="/usr/bin/pt-stalk" DAEMON_OPTS="--config /etc/pt-stalk.conf" NAME="pt-stalk" DESC="pt-stalk" PIDFILE="/var/run/${NAME}.pid" STALKHOME="/var/lib/pt-stalk" test -x $DAEMON || exit 1 [ -r /etc/default/pt-stalk ] && . /etc/default/pt-stalk #. /lib/lsb/init-functions sig () { test -s "$PIDFILE" && kill -$1 `cat $PIDFILE` } start() { if [[ -z $MYSQL_OPTS ]]; then HOME=$STALKHOME $DAEMON $DAEMON_OPTS else HOME=$STALKHOME $DAEMON $DAEMON_OPTS -- $MYSQL_OPTS fi return $? } stop() { if sig TERM; then while sig 0 ; do echo -n "." sleep 1 done return 0 else echo "$DESC is not running." return 1 fi } status() { if sig 0 ; then echo "$DESC (`cat $PIDFILE`) is running." return 0 else echo "$DESC is stopped." return 1 fi } log_begin_msg() { echo $1 } log_end_msg() { if [ $1 -eq 0 ]; then echo "Success" else echo "Failure" fi } case "$1" in start) log_begin_msg "Starting $DESC" start log_end_msg $? ;; stop) log_begin_msg "Stopping $DESC" stop log_end_msg $? ;; status) status ;; restart) log_begin_msg "Restarting $DESC" stop sleep 1 start log_end_msg $? ;; *) echo "Usage: $0 {start|stop|status|}" >&2 exit 1 ;; esac 

由于你的守护进程立即终止,我很确定,如果给/usr/bin/pt-stalk赋予了--daemonize选项,它可能不能及时地closures其中一个文件描述符stdinstdoutstderr ,并不能正确处理SIGHUP信号。

为了testing我的哪个假设是正确的,修改你的init脚本,以便startstartinput和输出从/dev/nullredirect到。 例:

 start </dev/null >/dev/null 2>/dev/null 

如果这消除了提前终止问题,通过一个接一个地去除这些redirect来缩小它。 这可能是pt-stalk只是早早地分叉而已。 在这种情况下,在start调用之后插入另一个sleep 1也可以解决这个问题。 如果出现SIGHUP信号的处理,那么也可以通过添加以下方法来修改init脚本:

 trap "echo SIGHUP ignored" 1 

在电话start和这之前:

 trap - 1 

在电话start

我没有下载pt-stalk ,也没有查看它,也没有testing我上述的理论。 这一切都来自我与其他守护进程的经验。