- 注意:
~/opt/bin/MemoryDiagnostics
是一个 bash 脚本并且是可执行的。
$ cat MemoryDiagnostics.service
[Unit]
Description=MemoryDiagnostics Service
[Service]
ExecStart="%h/opt/bin/MemoryDiagnostics"
SyslogIdentifier=MemoryDiagnosticsService
[Install]
WantedBy=default.target
$ systemctl --user enable MemoryDiagnostics.service
Created symlink /home/nikhil/.config/systemd/user/default.target.wants/MemoryDiagnostics.service → /home/nikhil/.config/systemd/user/MemoryDiagnostics.service.
然后重新启动。观察:重启后服务失败
$ systemctl --user status MemoryDiagnostics.service
● MemoryDiagnostics.service - MemoryDiagnostics Service
Loaded: loaded (/home/nikhil/.config/systemd/user/MemoryDiagnostics.service; enabled; vendor preset: enabled)
Active: failed (Result: exit-code) since Thu 2021-09-02 02:34:32 CEST; 11min ago
Process: 1549 ExecStart=/home/nikhil/opt/bin/MemoryDiagnostics (code=exited, status=1/FAILURE)
Main PID: 1549 (code=exited, status=1/FAILURE)
Sep 02 02:34:29 X550JX systemd[1147]: Started MemoryDiagnostics Service.
Sep 02 02:34:32 X550JX systemd[1147]: MemoryDiagnostics.service: Main process exited, code=exited, status=1/FAILURE
Sep 02 02:34:32 X550JX systemd[1147]: MemoryDiagnostics.service: Failed with result 'exit-code'.
- 手动完成时服务启动:
$ systemctl --user start MemoryDiagnostics.service
$ systemctl --user status MemoryDiagnostics.service
● MemoryDiagnostics.service - MemoryDiagnostics Service
Loaded: loaded (/home/nikhil/.config/systemd/user/MemoryDiagnostics.service; enabled; vendor preset: enabled)
Active: active (running) since Thu 2021-09-02 02:48:13 CEST; 4s ago
Main PID: 9941 (bash)
CGroup: /user.slice/user-1000.slice/[email protected]/MemoryDiagnostics.service
├─9941 bash /home/nikhil/opt/bin/MemoryDiagnostics
└─9970 sleep 121
Sep 02 02:48:13 X550JX systemd[1147]: Started MemoryDiagnostics Service.
为什么 shell 脚本在重新启动后失败,但在手动启动时工作得很好?
答案1
~/opt/bin/MemoryDiagnostics
正在退出,退出代码为 1。这意味着故障是应用程序内部的。令人失望的是,MemoryDiagnostics
没有将更多信息记录到 stderr,以便我们可以帮助提供它所需的信息。但我们可以做出一些猜测:
- 如果
MemoryDiagnostics
启动 GUI,则更WantedBy=default.target
改为WantedBy=graphical-session.target
. - 如果
MemoryDiagnistics
依赖于其他资源,我们可以添加After=
到我们的[Unit]
部分以确保依赖项已准备就绪。一些可能相关的依赖项可能是:After=bluetooth.target
如果您也在检查(或未能检查)蓝牙。After=default.target
如果您需要由以下机构筹集的其他服务default.target
- 在运行此命令之前需要准备好任何其他自定义单元(可能是安装或服务)。
如果您无法确定需要准备好哪个依赖项(或者该依赖项可能需要时间才能启动,但不使用 inotify),那么您始终可以添加ExecStartPre=/bin/sleep 5
人工 5 秒的启动延迟。
此方法更容易配置,但会增加不必要的延迟或有过早开始的风险。
如果您确实喜欢该ExecStartPre=sleep
方法,则不一定需要立即运行它,只需经常运行即可。那么你也可以考虑使用 a*.timer
来启动你的单元。在这种情况下,我会[Install]
从您的服务中删除该部分,并创建以下计时器:
# ~/.config/systemd/user/MemoryDiagnostics.timer
[Unit]
Description=MemoryDiagnostics Timer
[Timer]
OnActiveSec=5s
[Install]
WantedBy=default.target
然后systemctl --user enable MemoryDiagnostics.timer
让它处理执行服务。
这实际上等同于ExecStart=sleep
上面的解决方案,但也为您提供了额外的能力来添加/更改以下内容:
OnCalendar=
这将按计划运行您的诊断RandomizedDelaySec=
这将对服务的触发应用随机偏移,以避免同时触发大量服务。