如何确保 bash 脚本在 systemd 服务启动之前完成?

如何确保 bash 脚本在 systemd 服务启动之前完成?

我想要一个 bash 脚本完全的它的工作(不仅仅是开始)在某个systemd服务之前,据我所知,该解决方案涉及在其之前完成自己的服务已结束。

网络搜索可以找到有关如何开始的问题。据我了解,Before=选择是等到单位启动。因此,阅读时man systemd.service我只看到一种选择Type=forking::

当父进程退出时,服务管理器将认为该单元已启动。

即使我没有在脚本中分叉任何进程。我在这里说得对吗?这是否能保证(除了错误等)我的脚本将在服务Before=启动之前完成?

例如其他类型:Type=exec:

“而在服务进程中的 fork() 和 execve() 都成功之前,exec 将不会继续。”

我不清楚proceed这里的意思,同时阅读man execve我也不明白 systemd 如何知道是否execve成功:

execve() 成功后不返回,并且根据新加载程序的内容覆盖调用进程的文本、初始化数据、未初始化数据(bss)和堆栈。

据我所知,其他类型(notify、dbus)man在进程启动时需要特殊功能。

答案1

我认为你可以很好地type=oneshot使用RemainAfterExit=true;从文档

oneshot 的行为与 simple 类似;然而,主进程退出后,服务管理器将考虑该单元启动。然后它将启动后续单位。RemainAfterExit=对于此类服务特别有用。如果既没有指定也没有指定,Type=oneshot则为隐含的默认值。请注意,如果在没有服务的情况下使用此选项,则服务将永远不会进入“活动”单元状态,而是直接从“激活”转换到“停用”或“死亡”,因为没有配置应连续运行的进程。特别是,这意味着在这种类型的服务运行(并且尚未设置)之后,它将不会显示为随后启动,而是显示为死亡。Type=ExecStart=RemainAfterExit=RemainAfterExit=

可能还不太清楚,什么是主要流程是的,但是看看解释就会ExecStart=发现:

除非Type=forking设置,否则通过此命令行启动的进程将被视为守护进程的主进程。


编辑

请注意,这Type=oneshot是唯一允许多个ExecStart=选项的类型。它们按照出现的顺序依次执行,并且每个进程在运行时都是各自的主进程。

再次查看手册:

执行开始=

启动此服务时执行的命令。根据下面“命令行”部分中描述的规则,该值被分成零个或多个命令行。

除非 Type= 是一次性的,否则必须给出一个命令。当使用Type=oneshot时,可以指定零个或多个命令。可以通过在同一指令中提供多个命令行来指定命令,或者可以多次指定该指令以达到相同的效果。如果将此选项指定为空字符串,则要重置的命令列表将被重置,此选项之前的指定将无效。如果未指定 ExecStart=,则服务必须设置 RemainAfterExit=yes 和至少一个 ExecStop= 行。 (缺少 ExecStart= 和 ExecStop= 的服务无效。)

如果指定了多个命令,则按照命令在单元文件中出现的顺序依次调用这些命令。如果其中一个命令失败(并且不带“-”前缀),则其他行不执行,并且该单元被视为失败。

相关内容