如何在禁用 systemd 服务单元时运行命令?

如何在禁用 systemd 服务单元时运行命令?

我有以下 systemd 服务单元来设置笔记本电脑的电池阈值:

[Unit]
Description=Set Battery Charge Thresholds

[Service]
Type=oneshot
ExecStart=/usr/bin/tpacpi-bat -s --start 1 30
ExecStart=/usr/bin/tpacpi-bat -s --stop 1 85
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

我想要的是一种在禁用服务单元时运行命令的方法(这样我可以方便地将阈值设置回默认值)。这可能吗?

答案1

看看ExecStop或者ExecStopPost

执行停止

执行命令以停止通过 ExecStart= 启动的服务。此参数采用多个命令行,遵循与上面 ExecStart= 描述的相同方案。此设置的使用是可选的。运行此选项中配置的命令后,将根据 KillMode= 设置终止服务剩余的所有进程(请参阅 systemd.kill(5))。如果未指定此选项,则当请求服务停止时,通过发送 KillSignal= 中指定的信号来终止进程。支持说明符和环境变量替换(包括 $MAINPID,见上文)。

...

建议将此设置用于与请求干净终止的服务进行通信的命令。当执行使用此选项指定的命令时,应假设服务仍然完全启动并且能够对所有命令做出正确反应。对于事后清理步骤,请改用 ExecStopPost=。

执行停止后

服务停止后执行的附加命令。这包括使用 ExecStop= 中配置的命令、服务未定义任何 ExecStop= 或服务意外退出的情况。此参数采用多个命令行,遵循与 ExecStart= 描述的相同方案。这些设置的使用是可选的。支持说明符和环境变量替换。请注意,与 ExecStop= 不同的是,当服务无法正确启动并再次关闭时,将调用使用此设置指定的命令。

建议使用此设置进行清理操作,即使服务无法正确启动也应执行这些操作。即使服务中途启动失败并留下未完全初始化的数据,使用此设置配置的命令也需要能够运行。由于在执行使用此设置指定的命令时服务的进程已经终止,因此它们不应尝试与它们通信。

请注意,使用此设置配置的所有命令都将使用服务的结果代码以及主进程的退出代码和状态进行调用,这些代码和状态在 $SERVICE_RESULT、$EXIT_CODE 和 $EXIT_STATUS 环境变量中设置,请参阅 systemd.exec (5) 详细信息。

这两个都可以用来在服务停止时运行命令。

两者的主要区别:

  • ExecStop在主进程仍在运行时运行,并且只有在正常运行后停止服务时才会运行(意味着所有服务ExecStartExecStartPre必须成功,并且任何服务Conditions... 也必须通过。

  • ExecStopPost即使“服务意外退出”也会运行,这涵盖了故障。这样做的最大好处是当你有多个ExecStarts 时,如果其中一个成功而另一个失败,ExecStopPost可以用来尝试清理部分成功。

相关内容