我有一个脚本想要在下次系统启动时运行,但不在后续启动时运行。我想使用 systemd 来启动它,所以我在以下位置创建了一个服务文件/usr/lib/systemd/system/myscript.service
:
[Unit]
Description=My script.
[Service]
Type=oneshot
ExecStart=/opt/mypackage/bin/myscript
[Install]
WantedBy=multi-user.target
我可以告诉 systemd 在启动时使用systemctl enable myscript.service
.
我需要做什么才能阻止它在后续启动时运行?
我可以添加systemctl disable myscript.service
到脚本末尾,但这总是会禁用该服务。如果可能的话,我希望能够启用该服务,然后启动它,并在下次启动时仍然执行它。
答案1
您可以使用该ConditionPathExists=
指令(请参阅systemd.unit(5)
)来有条件地启动一个单元。这允许您使该设备永久启用,并通过删除一个简单的文件(暂时)禁用它。
systemctl start
systemd 中的“started at boot”和“started from”之间没有区别。解决方法是检查脚本中的正常运行时间,以便决定在下次启动时启用/禁用该单元(通过删除/创建文件ConditionPathExists=
)。
答案2
注意:这个答案扩展了答案经过蒂莫西·拉维尔 (蒂莫西之前在此网站上使用过 Siosm 这个名称),并包括替代解决方案。如果您同意第一部分,请投票给 Timothée 的答案。
与蒂莫西·拉维尔的回答,在单元服务文件的ConditionPathExists=
部分中使用(参见 systemd.unit(5)[Unit]
在 freedesktop.org或者在 man7.org)以使您的服务运行有条件。
例如,如果myscript
的职责是创建一个文件或文件夹一次,请添加反映这一点的启动条件:ConditionPathExists=!/path/to/folder
。请注意!
,它否定(反转)条件的含义;仅当路径不存在时才启动服务单元。
相反,您可以指向ConditionPathExists
一个文件,例如/var/tmp/myscript.on-next-reboot
脚本在成功运行后需要删除的文件。您或许可以将删除添加为单位ExecStartPost=
指令。
不过,一般来说,您应该尝试使系统正常工作,以便不需要重新启动后的操作。将事情设置为在下次启动时运行在态度上非常“像Windows”。 Linux 用户和管理员倾向于确定性、模块化和可预见的启动;让条件运行时值触发不同的引导路径会使引导系统更难以推理,并且更容易损坏。