我的问题:
我正在编写一个 bash 脚本,在其中我想检查给定的服务是否正在运行。
我知道如何手动执行此操作,使用$ service [service_name] status
.
但是(特别是自从转向 systemd 以来)打印出一大堆文本,解析起来有点混乱。我假设有一个针对具有简单输出或我可以检查的返回值的脚本的命令。
但谷歌搜索只会产生大量“哦,只是ps aux | grep -v grep | grep [service_name]
”结果。这不是最佳实践,不是吗?如果该命令的另一个实例正在运行,但不是由 SysV 初始化脚本启动的实例,该怎么办?
或者我应该闭嘴并用一点 pgrep 弄脏我的手?
答案1
systemctl
有一个is-active
为此的子命令:
systemctl is-active --quiet service
如果处于活动状态,将以状态零退出service
,否则以非零状态退出,这使其成为脚本的理想选择:
systemctl is-active --quiet service && echo Service is running
如果省略,--quiet
它也会将当前状态输出到其标准输出。
即使没有运行任何内容来提供服务,某些单元也可以处于活动状态:标记为“RemainAfterExit”的单元如果成功退出,则被视为活动状态,其想法是它们提供不需要守护程序的服务(例如他们配置系统的某些方面)。然而,涉及守护进程的单元只有在守护进程仍在运行时才会处于活动状态。
一次性单位没有“RemainAfterExit”永远不会进入活动单元状态,因此is-active
永远不会成功;要处理此类单位,is-active
可以分析 的文本输出:
systemctl is-active service
这将为当前正在运行的一次性单元输出“activating”,为当前未运行但上次运行成功(如果有)的一次性单元输出“inactive”,为当前未运行的一次性单元输出“failed”并且上次运行时失败了。is-active
这些单位总是返回非零状态,因此运行
systemctl is-active service ||:
如果你需要忽略它。
答案2
systemctl
确实有适合脚本编写的模式;使用show
而不是status
,并添加-p
/--properties
和--value
选项以仅获得您想要的输出。
这是一个示例(来自 Ubuntu 17.04 系统):
$ systemctl show -p SubState --value NetworkManager
running
运行(或以其他方式)是一个SubState
.如果您想知道服务是否处于活动状态,请使用该属性ActiveState
$ systemctl show -p ActiveState --value x11-common
inactive
$ systemctl show -p SubState --value x11-common
dead
注释来自man
:
show [PATTERN...|JOB...]
Show properties of one or more units, jobs, or the manager
itself. If no argument is specified, properties of the
manager will be shown. If a unit name is specified, properties
of the unit are shown, and if a job ID is specified,
properties of the job are shown. By default, empty properties
are suppressed. Use --all to show those too. To select specific
properties to show, use --property=. This command is intended
to be used whenever computer-parsable output is required. Use
status if you are looking for formatted human-readable output.
-p, --property=
When showing unit/job/manager properties with the show command,
limit display to properties specified in the argument. The
argument should be a comma-separated list of property names,
such as "MainPID". Unless specified, all known properties are
shown. If specified more than once, all properties with the
specified names are shown. Shell completion is implemented for
property names.
--value
When printing properties with show, only print the value, and
skip the property name and "=".
要查看服务的可用属性,请运行(例如, for polkit
)
systemctl show -a polkit
LoadState
不幸的是, 、ActiveState
和的可能值SubState
在联机帮助页中没有记录;相反,它们记录在 D-Bus 接口描述中org.freedesktop.systemd1
:https://www.freedesktop.org/software/systemd/man/org.freedesktop.systemd1.html
LoadState
包含一个状态值,反映该单元的配置文件是否已加载。当前定义了以下状态:“loaded
”、“error
”和“masked
”。 “loaded
”表示配置加载成功。 “error
”表示配置加载失败。该LoadError
字段(见下文)包含有关此故障原因的信息。 “masked
”表示该单元当前被屏蔽(即符号链接到/dev/null
或为空)。请注意,LoadState
与 完全正交ActiveState
(见下文),因为没有有效加载配置的单元可能处于活动状态(因为配置可能已在单元已处于活动状态时重新加载)。
ActiveState
包含反映单元当前是否处于活动状态的状态值。当前定义了以下状态:“active
”、“reloading
”、“inactive
”、“failed
”、“activating
”和“deactivating
”。 “active
”表示该单元处于活动状态(显然......)。 “reloading
”表示该单元处于活动状态并且当前正在重新加载其配置。 “inactive
”表示它处于非活动状态,并且先前的运行已成功或尚未发生先前的运行。 “failed
”表示它处于非活动状态,并且之前的运行未成功(有关其原因的更多信息可在单元类型特定接口上找到,例如“结果”属性中的服务,请参见下文)。 “activating
”表示该单元之前处于非活动状态,但当前正在进入活动状态。相反,“deactivating
”表示该单元当前处于停用过程中。
SubState
ActiveState
对覆盖但了解特定于单元类型的更细粒度状态的同一状态机的状态进行编码。其中ActiveState
仅覆盖六个高级状态,SubState
可能覆盖映射到六个高级状态的更多低级单元类型特定状态。请注意,多个低级状态可能映射到相同的高级状态,但反之则不然。并非所有高级别状态在所有单位类型上都有低级别对应项。此时,低级状态未在此处记录,并且比上面解释的常见高级状态更有可能在以后扩展。
有很多房产,所以如果您知道自己在寻找什么......
$ systemctl show - polkit | grep Active
ActiveState=active
ActiveEnterTimestamp=Thu 2020-07-02 07:24:40 IST
ActiveEnterTimestampMonotonic=6682102
ActiveExitTimestamp=
ActiveExitTimestampMonotonic=0
答案3
作为对 Zanna 答案的补充,引入了--value
选项systemctl show
systemd 版本 230。因此,它可能在某些发行版(例如 debian jessie)上不可用。
在这种情况下,可以使用 sed 模拟该选项:
$ systemctl show -p ActiveState sshd | sed 's/ActiveState=//g'
active
$ systemctl show -p SubState sshd | sed 's/SubState=//g'
running
答案4
我发现这对于命令行执行或正在制作脚本很有用。
复制自@StephenKitt
这将检查服务是否已关闭并执行服务重启
systemctl is-active --quiet <service name> || <service name> restart
那里||
检查 systemctl 的返回值是否非零,意思是如果它没有按照作者的解释激活。