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

Bash编写服务检测脚本时运行时长判断失效问题求助

问题根因

你现有脚本跑不通是几个基础Bash语法和逻辑设计错误叠加导致的:

  • systemctl is-active --quiet 本身通过退出码返回结果:退出码0代表服务处于active状态,非0代表异常,你后面追加的= active会被当成命令参数传入,直接导致命令执行逻辑错误。
  • Bash原生不支持直接写$SERVICE_UP_TIME > 60s做数值比较:在(( ))算术判断结构外,>是文件重定向符号,你这么写不会做数值判断,反而会在当前目录创建一个名为60s的空文件;同时算术比较要求两边都是纯数字,不能带s这类单位后缀。
  • wait 60s用法完全错误:wait是Bash内置命令,作用是等待指定后台进程执行结束,没有延时功能,做时间等待要用sleep命令。
  • 逻辑设计有缺陷:你只在脚本开头取了一次服务启动时间,后续没有重新校验,服务如果在等待过程中重启、启动时间重置,脚本完全感知不到,满足不了“检测服务重启报错误”的要求。
  • 启动时间解析方式鲁棒性差:直接解析systemctl status的文本输出很容易受系统语言、systemd版本差异影响,取到的时间格式不对就会导致计算运行时长失败。
优化后可复用脚本

这个版本适配任意systemd管理的服务,修复了上述所有问题,完全匹配你要的检测逻辑:

#!/bin/bash
# 可替换为任意需要检测的systemd服务名
SERVICE="logstash"
# 要求的最小运行时长阈值,单位秒
UPTIME_THRESHOLD=60

# 统一C语言环境,避免时间解析受系统语言影响
export LANG=C LC_ALL=C

# 记录首次检测到的服务启动时间,用于判断服务是否重启
last_start_time=0

while true; do
    # 第一步:检测服务当前状态
    svc_state=$(systemctl is-active "$SERVICE")
    if [ "$svc_state" != "active" ]; then
        echo "ERROR: 服务$SERVICE当前状态为$svc_state,未正常运行"
        exit 1
    fi

    # 第二步:通过systemctl原生接口取服务精确启动时间,不解析易变的status文本
    current_start_raw=$(systemctl show -p ActiveEnterTimestamp --value "$SERVICE")
    current_start_ts=$(date -d "$current_start_raw" +%s)
    current_ts=$(date +%s)
    current_uptime=$((current_ts - current_start_ts))

    # 第三步:检测服务是否发生重启(启动时间比上次记录的更晚)
    if [ $last_start_time -ne 0 ] && [ $current_start_ts -gt $last_start_time ]; then
        echo "ERROR: 服务$SERVICE发生重启,运行时长已重置"
        exit 1
    fi
    last_start_time=$current_start_ts

    # 第四步:判断运行时长是否达标
    if [ $current_uptime -ge $UPTIME_THRESHOLD ]; then
        echo "$SERVICE 运行正常,已稳定运行超过$UPTIME_THRESHOLD秒,开始执行后续检测项"
        break
    fi

    # 未达阈值则动态计算等待时间,避免无效等待
    wait_sec=$((UPTIME_THRESHOLD - current_uptime))
    echo "$SERVICE 当前已运行${current_uptime}秒,还差${wait_sec}秒达到阈值,等待中..."
    sleep $wait_sec
done

# 后续其他检测项写在这里
适配说明
  • 只需要修改开头SERVICE变量的值,就可以复用到任意systemd托管的服务检测场景,不需要调整其他逻辑
  • 所有系统状态取值都通过systemctl show拿结构化属性,不解析自由格式的systemctl status输出,跨版本、跨语言环境兼容性拉满
  • 每次循环都会重新拉取服务状态和启动时间,一旦出现服务失败、意外重启的情况会立刻报错退出,不会漏检
  • 等待时长是动态计算的,不会固定等待60秒,服务运行时长刚到阈值就会立刻进入后续检测流程,没有多余耗时

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 22:18:42