You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Bash脚本按序停止服务及状态检查的技术问题求助

Bash脚本实现服务按序停止与状态检查

需求

  • 根据名称中的特定关键词查找特定服务
  • 按指定顺序(如service_1、service_2等)停止这些服务
  • 检查服务是否已停止,若仍有运行中的服务则输出其名称

现有实现进展

1. 根据关键词获取服务

service_1=$(ls /etc/systemd/system | grep -e text1 | awk -F ' ' '{print $1}')
service_2=$(ls /etc/systemd/system | grep -e text2 | awk -F ' ' '{print $1}')
service_3=$(ls /etc/systemd/system | grep -e text3 | awk -F ' ' '{print $1}')

2. 按顺序停止服务

if [ ! -z "$service_1" ] # if service exists
then
      systemctl stop $service_1
else
      :
fi

if [ ! -z "$service_2" ] # if service exists
then
      systemctl stop $service_2
else
      :
fi

if [ ! -z "$service_3" ] # if service exists
then
      systemctl stop $service_3
else
      :
fi

3. 尝试检查服务状态

service_1_status=$(systemctl status $service_1 | grep -e "inactive")
service_2_status=$(systemctl status $service_2 | grep -e "inactive")
service_3_status=$(systemctl status $service_3 | grep -e "inactive")

# 尝试的状态检查循环(无法正常工作)
arr=($service_1_status $service_2_status $service_3_status $service_q_inf_status)
for i in "${arr[@]}"
do
      if "${arr[$i}" != "inactive"
      then
            echo $i
      else
            echo "All Services are now Stopped"
      fi
done

遇到的问题

  1. 停止服务时,脚本不会等待前一个服务完全停止就执行下一个操作,无法保证按序停止的可靠性
  2. 状态检查的循环逻辑错误,无法正确识别运行中的服务

解决方案

1. 实现按序等待服务停止

编写通用函数负责停止服务并循环等待其完全停止(可设置超时),再按顺序调用:

# 停止服务并等待其完全停止的函数
stop_and_wait() {
    local service=$1
    # 跳过空服务名
    if [ -z "$service" ]; then
        return
    fi

    echo "开始停止服务: $service"
    systemctl stop "$service"

    # 设置超时时间(单位:秒)
    local timeout=30
    local wait_count=0

    # 循环检查服务状态
    while systemctl is-active --quiet "$service"; do
        if [ $wait_count -ge $timeout ]; then
            echo "超时警告: 等待$service停止超过$timeout秒,终止等待"
            break
        fi
        sleep 1
        wait_count=$((wait_count + 1))
    done

    # 最终状态确认
    if systemctl is-active --quiet "$service"; then
        echo "错误: $service未能在指定时间内停止"
    else
        echo "$service已成功停止"
    fi
}

# 按指定顺序执行停止操作
stop_and_wait "$service_1"
stop_and_wait "$service_2"
stop_and_wait "$service_3"

2. 正确实现服务状态检查

直接循环服务列表,用systemctl is-active命令(比grep状态输出更可靠)判断运行状态:

# 定义待检查的服务列表
target_services=("$service_1" "$service_2" "$service_3")
local has_running=0

echo "=== 服务状态检查 ==="
for service in "${target_services[@]}"; do
    if [ -n "$service" ]; then
        if systemctl is-active --quiet "$service"; then
            echo "⚠️ $service 仍在运行"
            has_running=1
        fi
    fi
done

if [ $has_running -eq 0 ]; then
    echo "✅ 所有服务已停止"
fi

额外优化:更可靠的服务查找方式

替换原有的ls + grep方式,改用systemctl原生命令查找服务:

# 根据关键词查找systemd服务(仅匹配.service文件)
service_1=$(systemctl list-unit-files --full | grep -E "text1.*\.service" | awk '{print $1}')
service_2=$(systemctl list-unit-files --full | grep -E "text2.*\.service" | awk '{print $1}')
service_3=$(systemctl list-unit-files --full | grep -E "text3.*\.service" | awk '{print $1}')

内容的提问来源于stack exchange,提问作者Mostafa Ramzy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 01:05:17