AnQiCMS计划任务中的`stop.sh`脚本,其内部逻辑是怎样的?

作为一位资深的网站运营专家,我深知每一个脚本命令背后都承载着系统稳定运行的重任。在AnQiCMS这样一款高效、简洁的内容管理系统中,计划任务脚本更是我们日常维护和管理不可或缺的工具。今天,我们就来深入探讨一下AnQiCMS计划任务中stop.sh脚本的内部逻辑,揭开它如何优雅地停止服务,保障我们网站平稳过渡的奥秘。

深度解析AnQiCMS计划任务中的stop.sh脚本

AnQiCMS作为一款基于Go语言开发的企业级内容管理系统,以其高性能、高并发的特点服务于广大中小企业和内容运营团队。在系统维护、版本升级或故障排查时,我们往往需要暂停或重启核心服务。stop.sh脚本正是为此而生,它以简洁而高效的方式,确保AnQiCMS的主进程能够被安全地终止。这个脚本通常作为计划任务的一部分,或者在需要手动停止服务时被执行。

为了更好地理解stop.sh的工作原理,我们首先来看一下它的典型内容:

#!/bin/bash
### stop anqicms
# author fesion
# the bin name is anqicms
BINNAME=anqicms
BINPATH="$( cd "$( dirname "$0"  )" && pwd  )"

# check the pid if exists
exists=`ps -ef | grep '\<anqicms\>' |grep -v grep |awk '{printf $2}'`
echo "$(date +'%Y%m%d %H:%M:%S') $BINNAME PID check: $exists" >> $BINPATH/check.log
echo "PID $BINNAME check: $exists"
if [ $exists -eq 0 ]; then
    echo "$BINNAME NOT running"
else
    echo "$BINNAME is running"
    kill -9 $exists
    echo "$BINNAME is stop"
fi

现在,让我们逐行剖析这段脚本的内部逻辑。

首先,#!/bin/bash 是一个标准的Shebang,它告诉操作系统这个脚本应该由/bin/bash解释器来执行。紧接着的几行以#开头的文字是注释,它们解释了脚本的用途、作者以及主程序的二进制文件名称,这对于后续的维护和理解脚本意图非常有帮助。

脚本的核心部分始于变量定义:

  • BINNAME=anqicms:这个变量定义了AnQiCMS主程序的二进制可执行文件名称,默认为anqicms。在查找和终止进程时,这个名称是关键标识。
  • BINPATH="$( cd "$( dirname "$0" )" && pwd )":这一行代码的目的是获取当前脚本文件所在的绝对路径。dirname "$0"会返回脚本文件所在的目录,cd进入该目录,然后pwd打印出当前工作目录的绝对路径。这样做的好处是,无论脚本从哪个位置被调用,它都能准确地知道自己的“家”在哪里,从而正确地访问日志文件或二进制文件。

接下来是进程检测的逻辑,这也是stop.sh最核心的步骤: exists=ps -ef | grep ‘<anqicms>’ |grep -v grep |awk ‘{printf $2}’” 这行命令是一个管道操作,它分四步完成AnQiCMS进程ID(PID)的查找:

  1. ps -ef:列出当前系统上所有运行中的进程,并显示它们的详细信息,包括PID、用户、CPU使用率等。
  2. grep '\<anqicms\>':从ps -ef的输出中,筛选出包含anqicms字样的行。这里使用\<\>是为了确保精确匹配完整的“anqicms”这个词,而不是匹配“myanqicms”或者“anqicms_test”这类包含anqicms的字符串,避免误杀。
  3. grep -v grep:由于上一步的grep命令本身也会包含anqicms这个字符串(例如:grep \<anqicms\>),这一步的作用是过滤掉grep命令自身的进程,确保我们只关注AnQiCMS主程序的进程。
  4. awk '{printf $2}'ps -ef的输出格式中,第二个字段通常就是进程ID(PID)。awk命令在这里负责提取这个字段。printf而非print的使用是为了避免在提取PID后产生多余的换行符,确保exists变量中只包含纯粹的PID数字。

通过这一系列精妙的管道操作,脚本能够准确地获取到AnQiCMS主程序的PID,并将其存储在exists变量中。

脚本随后会记录这次进程检测的结果:

  • echo "$(date +'%Y%m%d %H:%M:%S') $BINNAME PID check: $exists" >> $BINPATH/check.log:将带有时间戳、二进制文件名和检测到的PID信息追加写入到check.log文件中,这对于日后排查问题、审计操作历史非常有用。
  • echo "PID $BINNAME check: $exists":同时将这些信息输出到控制台,方便实时查看脚本执行状态。

最后,脚本进入条件判断阶段,根据是否找到AnQiCMS进程来决定下一步操作:

  • if [ $exists -eq 0 ]; then:如果exists变量的值是0,这意味着没有找到AnQiCMS的进程,即服务没有在运行。
    • echo "$BINNAME NOT running":脚本会打印一条消息,指示AnQiCMS服务没有运行,无需停止。
  • else:如果exists变量的值不是0,说明成功获取到了AnQiCMS的PID,服务正在运行。
    • echo "$BINNAME is running":打印消息,表明AnQiCMS正在运行。
    • kill -9 $exists这是停止服务的关键命令kill命令用于向进程发送信号,-9代表SIGKILL信号,这是一个强制终止信号。它会立即杀死目标进程,而不给进程执行任何清理操作