当前位置:首页 > 文章列表 > 文章 > linux > systemd 怎样用 unit 状态属性做脚本判断

systemd 怎样用 unit 状态属性做脚本判断

来源:17golang原创 2026-10-24 22:34:57 0浏览 收藏

脚本判断 systemd 服务时,推荐使用 systemctl show,不要直接解析 systemctl status 的展示文本。show 可以按属性取值,输出更适合脚本消费;常用的 LoadState、ActiveState、SubState 和 Result 分别回答“配置有没有加载”“当前是否处于活动状态”“更细的 unit 状态是什么”“上次执行结果如何”。

官方地址:https://www.freedesktop.org/software/systemd/man/latest/systemctl.html

下面把这几个属性与三种常见判断方案放在一起比较,最后给出一个可以直接改成监控脚本的 shell 示例。

脚本判断为什么优先使用 systemctl show

systemctl status 适合人看:它会把描述、进程、日志摘要和状态拼成一段展示文本。脚本若依赖其中某一行,容易受到本地化、换行、日志长度和 systemd 版本显示方式影响。systemctl show 的定位不同,官方文档明确把它用于机器可解析的属性输出,并支持用 --property= 限定字段。

常见选择可以这样判断:

方式适合场景主要取舍
systemctl status人工排查和查看日志摘要信息丰富,但不适合作为稳定解析接口
systemctl is-active只关心是否处于 active简单直接,不能表达加载错误和细分状态
systemctl show脚本、巡检和监控需要自己定义属性组合与退出码
systemctl show、属性筛选和 unit 状态属性之间的静态关系说明图
图1:结构说明图,展示脚本读取 systemctl show 属性时的字段边界,不是终端截图或运行证据。

先分清四类 unit 状态属性

LoadState 反映 unit 定义是否成功加载,例如 loaded、error 或 masked。它和运行状态不是一回事:一个 unit 的配置加载状态与当前活动状态需要分别判断。

ActiveState 是较高层的状态,常见值包括 active、inactive、failed、activating 和 deactivating。SubState 更细,具体值会随 unit 类型变化,例如 service 的等待状态不能简单套用到 socket 或 mount。脚本要判断“已经能提供服务”,通常以 ActiveState=active 为主,而不是把所有 SubState 值写死。

Result 更适合在失败后补充原因线索。它不是当前运行状态的替代品:服务可能已经重新启动并处于 active,但脚本仍然需要结合上下文决定是否读取此前的结果。

用属性筛选减少脚本解析噪声

只取一个属性时,可以把属性名和值分开输出。下面的函数把“命令失败”和“属性值不是预期”分开处理;注释解释了变量和退出码的用途,示例本身不依赖具体服务名。

#!/usr/bin/env bash
set -u

unit="${1:-example.service}" # 第一个参数是待判断的 unit,缺省使用示例名

if ! state="$(systemctl show "$unit" --property=ActiveState --value 2>/dev/null)"; then
  echo "无法读取 unit: $unit" >&2
  exit 2 # 读取失败属于检查错误,不把它误报成服务未运行
fi

case "$state" in
  active|reloading)
    echo "$unit 可用,当前状态为 $state"
    exit 0 # 监控或上游脚本可把 0 视为通过
    ;;
  activating|deactivating)
    echo "$unit 正在切换状态:$state" >&2
    exit 3 # 暂态单独编码,便于上游重试或延迟告警
    ;;
  failed|inactive)
    echo "$unit 不可用,当前状态为 $state" >&2
    exit 1 # 明确的不可用状态使用失败码
    ;;
  *)
    echo "$unit 返回未覆盖状态:$state" >&2
    exit 4 # 新增状态不静默放行,先交给调用方处理
    ;;
esac

这里把 reloading 视为暂时可用,是一种业务选择,不是所有服务都适用。若发布过程中的重载会影响请求,就应把它归入暂态分支。脚本的关键不是枚举越多越好,而是先定义“可用”“暂态”“不可用”和“检查失败”四个结果。

什么时候需要组合判断

只看 ActiveState 适合简单存活检查;需要区分 unit 文件问题、被屏蔽和服务自身失败时,再同时读取多个属性。可以保留属性名,便于日志直接说明判断依据:

unit="${1:-example.service}" # 允许调用方传入具体服务名
props="$(systemctl show "$unit" \
  --property=LoadState,ActiveState,SubState,Result,UnitFileState 2>/dev/null)" || {
  echo "systemctl show 执行失败:$unit" >&2
  exit 2 # 命令层失败与 unit 自身 failed 分开
}

printf '%s\n' "$props" # 保留属性名,方便日志和后续解析

case "$props" in
  *"LoadState=masked"*)
    echo "unit 已被屏蔽" >&2
    exit 5 # masked 是配置/启用层问题,不等同于普通 inactive
    ;;
  *"ActiveState=active"*)
    echo "unit 正在活动状态"
    exit 0 # 高层状态满足时,通常无需绑定某个 SubState
    ;;
  *"ActiveState=failed"*)
    echo "unit 失败,继续查看 Result 和日志" >&2
    exit 1 # failed 只表示失败,需要 Result 补充原因
    ;;
  *)
    echo "unit 当前不是可用状态" >&2
    exit 3 # inactive、activating 等状态交给上游策略处理
    ;;
esac

如果需要稳定的键值解析,应该让属性名和值保持一行一项,并只匹配明确的键名;不要对整段 status 文本做模糊正则。对不确定的状态保守返回非零码,等调用方决定重试、告警还是进入人工排查。

LoadState、ActiveState、SubState、Result 与脚本分支返回码的静态关系说明图
图2:关系说明图,展示四类状态属性如何对应脚本的判断边界与返回码,不是执行流程图或真实运行截图。

三种方案怎么选

健康检查只需要“现在是否 active”时,systemctl is-active --quiet unit.service 更短;脚本需要打印稳定字段或同时判断多个维度时,用 systemctl show --property=...;开发者正在定位启动失败、依赖关系或日志时,回到 systemctl status 和日志工具更合适。不要为了统一而让所有脚本都读取完整属性集合,属性越多,策略越容易把互不相关的状态耦合在一起。

目标推荐入口判断边界
健康探针is-active --quiet只表达当前是否 active
自动化脚本show --property明确属性、暂态和异常码
人工排错status 加日志查看上下文,不把展示文本当接口

最后记住两个边界:SubState 的值依赖 unit 类型,不能跨 service、socket、mount 直接复用;LoadState 与 ActiveState 彼此独立,判断配置是否存在和判断服务是否运行要分开写。

常见问题

为什么不用 systemctl status 的 Active 行?

它是面向人的格式化展示,适合排查,不适合让脚本依赖固定文本。脚本应优先使用属性输出或专门的退出码接口。

ActiveState=active 就一定代表业务请求正常吗?

不一定。它说明 unit 处于活动状态,不等于应用层接口、依赖服务或业务数据已经健康;业务探针仍需单独设计。

为什么 SubState 不能直接写成唯一判断条件?

SubState 是 unit 类型相关的细分状态,同一个词在不同类型中的含义和可用性可能不同。跨类型脚本应先用 ActiveState,再按具体类型补充 SubState。

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
Linux PSI 怎样读取 memory pressure 的平均值Linux PSI 怎样读取 memory pressure 的平均值
上一篇
Linux PSI 怎样读取 memory pressure 的平均值
findmnt 怎样识别 overlay 挂载的上层目录
下一篇
findmnt 怎样识别 overlay 挂载的上层目录
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • PubMedQA数据集详解:生物医学问答基准、功能与应用指南
    PubMedQA
    深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
    669次使用
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    686次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    733次使用
  • 斯坦福HELM:大语言模型Holistic Evaluation整体评估框架详解
    HELM
    深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
    701次使用
  • MMBench详解:多模态大模型基准测试、功能特点与使用指南
    MMBench
    MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
    536次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议 和 隐私政策
返回登录
  • 重置密码