tri*_*ger 10 linux debian systemd
我有一个运行软件的服务,如果它们不存在,它会生成一些配置文件,如果它们存在,则读取它们。我一直面临的问题是这些文件有时会损坏,导致软件无法启动,从而导致服务失败。在这种情况下,我想删除这些文件并重新启动服务。
我尝试通过这样做来创建一个应该在失败时执行的服务:
[Service]
ExecStart=/bin/run_program
OnFailure=software-fail.service
Run Code Online (Sandbox Code Playgroud)
这项服务在哪里:
[Service]
ExecStart=/bin/rm /file/to/delete
ExecStop=systemctl --user start software.service
Run Code Online (Sandbox Code Playgroud)
然而,问题是该服务不会启动,即使该服务已失败。
我试着做
systemctl --user enable software-fail.service
Run Code Online (Sandbox Code Playgroud)
但是每次系统启动时它都会启动,就像任何其他服务一样。
我的临时解决方案是使用
ExecStopPost=/bin/rm /file/to/delete
Run Code Online (Sandbox Code Playgroud)
但这不是一个令人满意的解决方法,因为它总是会在停止服务时删除文件,无论是否因为失败。
失败时的输出:
? software.service - Software
Loaded: loaded (/home/trippelganger/.config/systemd/user/software.service; enabled; vendor preset: enabled)
Active: failed (Result: exit-code) since Fri 2018-05-04 09:05:26 CEST; 5s ago
Process: 1839 ExecStart=/bin/run_program (code=exited, status=1/FAILURE)
Main PID: 1839 (code=exited, status=1/FAILURE)
May 04 09:05:26 trippelganger systemd[595]: software.service: Main process exited, code=exited, status=1/FAILURE
May 04 09:05:26 trippelganger systemd[595]: software.service: Unit entered failed state.
May 04 09:05:26 trippelganger systemd[595]: software.service: Failed with result 'exit-code'.
Run Code Online (Sandbox Code Playgroud)
systemctl --user status software-fail.service 的输出是:
? software-fail.service - Delete corrupt files
Loaded: loaded (/home/trippelganger/.config/systemd/user/software-fail.service; disabled; vendor preset: enabled)
Active: inactive (dead)
Run Code Online (Sandbox Code Playgroud)
fil*_*den 10
为了在服务失败时执行一些清理,您可以使用ExecStopPost=,无论服务是否成功都会执行。
在您运行的代码中ExecStopPost=,您可以使用$SERVICE_RESULT、$EXIT_CODE或 之一$EXIT_STATUS来确定失败条件并采取相应措施。请参阅有关这些环境变量的文档以检查哪一个适合您。
然后您可以使用,Restart=on-failure以便 systemd 在失败时尝试重新启动您的设备。
把它们放在一起,这就是它的样子。假设run_program每当文件损坏时都会以状态 2 退出(希望您可以将其调整为上述文档中的其他故障情况),这应该有效:
[Service]
ExecStart=/bin/run_program
ExecStopPost=/bin/sh -c 'if [ "$$EXIT_STATUS" = 2 ]; then rm /file/to/delete; fi'
Restart=on-failure
Run Code Online (Sandbox Code Playgroud)
(注意:双美元符号$$是为了将其转义到 systemd,因此外壳会看到$EXIT_STATUS并访问该变量。使用单个美元符号也可以,但是 systemd 会进行替换,外壳会看到[ "2" = 2 ],这可以说也有效......无论如何,您可以通过将所有这些逻辑放入shell脚本并通过其完整路径调用它来绕过大部分,这ExecStopPost=可能会更好,您还可以轻松地向脚本添加更多命令,例如记录为从错误状态中恢复而采取的操作。)
希望这会给您足够的指导,以了解如何根据您的特定情况正确配置它!
注意:您可能想要使用ExecStopPost=而不是OnFailure=这里(请参阅我的其他答案),但这试图解决您的OnFailure=设置不起作用的原因。
OnFailure=不启动单元的问题可能是因为它在错误的部分,它需要在该[Unit]部分而不是[Service].
你可以试试这个:
# software.service
[Unit]
Description=Software
OnFailure=software-fail.service
[Service]
ExecStart=/bin/run_program
Run Code Online (Sandbox Code Playgroud)
和:
# software-fail.service
[Unit]
Description=Delete corrupt files
[Service]
ExecStart=/bin/rm /file/to/delete
ExecStop=/bin/systemctl --user start software.service
Run Code Online (Sandbox Code Playgroud)
我可以使用此设置使其正常工作。
但请注意,使用OnFailure=在这里并不理想,因为您无法真正说出程序失败的原因,并且ExecStop=通过/bin/systemctl start直接调用将它的另一个开始链接起来非常困难......使用的解决方案ExecStopPost=和查看退出状态绝对是优越的。
如果您定义OnFailure=inside [Service],则 systemd(至少来自 Fedora 27 的版本 234)会抱怨:
software.service:6: Unknown lvalue 'OnFailure' in section 'Service'
Run Code Online (Sandbox Code Playgroud)
不确定您是否在日志中看到了它......(也许这是在最近的 systemd 中添加的?)这应该暗示那里发生了什么。
| 归档时间: |
|
| 查看次数: |
12047 次 |
| 最近记录: |