我有一个以下类型的 systemd 服务文件。
[Unit]
Description=Mount some special file systems
After=local-fs.target
Before=syslog.service
[Service]
Type=oneshot
ExecStart=/root/some-complicated-mounts.sh
ExecStop=/root/some-complicated-umounts.sh
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
该脚本/root/some-complicated-mounts.sh
安装一些文件系统。
在我添加该声明之前,该服务无法正常工作RemainAfterExit=yes
。如果没有此语句,脚本完成的安装似乎会消失,即使根据日志,脚本已成功执行。
我想知道为什么我需要该RemainAfterExit=yes
声明以及 systemd 文档中描述此行为的位置。
答案1
如果没有这个单一服务将无法工作,RemainAfterExit=yes
因为 systemd 会认为脚本完成后该单元将立即变为非活动状态some-complicated-mounts.sh
,此时它将停止该单元,其中包括执行命令ExecStop=
,然后继续卸载文件系统通过执行some-complicated-umounts.sh
脚本。
使用RemainAfterExit=yes
解决了这个问题,因为该单元在命令完成后被视为启动ExecStart=
,并且是保持活跃状态。因此,ExecStop=
仅当设备明确停止(使用systemctl stop
命令)或作为正常关闭过程的一部分(所有设备均停止时),该命令才会执行。
关于文档,systemd 文档实际上有一个针对这种情况的示例:请参阅“示例 3.可停止的一次性服务”在 systemd.service(5) 的手册页上。该示例用例的描述如下:
与一次性服务类似,有时有些单元需要执行一个程序来设置某些内容,然后执行另一个程序来关闭它,但是当它们被视为“启动”时,没有进程保持活动状态。 [...]
为此,systemd 知道设置
RemainAfterExit=yes
,如果启动操作成功退出,那么 systemd 就会认为该单元处于活动状态。
还与实施例2,这是一个没有ExecStop=
.
(不幸的是,文档RemainAfterExit=
它本身太简洁了,并没有真正涉及这些细节。此处可能有机会改进该选项的文档。)