Systemd脚本在执行完ExecStart后立即执行了ExecStop

33

这是我的 Systemd 脚本:

[Unit]
Description=RDS Services

[Service]
WorkingDirectory=/home/rdsdb2/script_rds/
Type=oneshot
ExecStart=/bin/bash start_services.sh
ExecStop=/bin/bash stop_services.sh
KillMode=process

[Install]
WantedBy=multi-user.target

我无法理解为什么它会按顺序执行(在系统启动或我手动启动时)ExecStart 和 ExecStop。

你能帮我吗?

提前感谢你。


2
这个问题应该发到 http://unix.stackexchange.com 上。祝你好运。 - shellter
1
不要从Systemd运行实际调用您服务的外部脚本。这样做是行不通的。让systemd实际启动服务。 - Michael Hampton
3个回答

75

Type=oneshot用于单次执行的操作,例如文件系统检查或清理,这些systemd单元将等待由ExecStart指定的进程终止后,通过运行由ExecStop指定的进程来停用。

Type=simple(默认设置)用于当配置了由ExecStart指定的进程为服务的主要进程时。这些unit将等到由ExecStart指定的进程返回,然后通过运行由ExecStop指定的进程来停用。

使用RemainAfterExit=yes将认为服务仍然处于活动状态,即使其所有进程已经返回,因此ExecStop指定的进程不会自动运行。但是,不推荐使用此设置,因为即使服务崩溃,它仍将显示为处于活动状态。此设置默认禁用。

Type=forking用于指定由ExecStart指定的进程在启动完成后将退出,而其子进程将在后台继续运行。这是传统UNIX守护进程的行为,并且在您的情况下是推荐选择。 ExecStop设置是可选的,用于与服务通信以进行干净的终止。如果服务崩溃,则会运行由ExecStop指定的进程。如果没有任何ExecStop选项,则systemctl stop servicename命令将仅杀死unit剩余的进程,如KillMode选项所指定的那样。


1
感谢您分享这个极好的解释;它很有帮助,谢谢。如果可能的话,请添加一些关于systemctl理解的链接。 - RavinderSingh13
这里的ExecStop语义有变化吗?https://www.freedesktop.org/software/systemd/man/systemd.service.html#ExecStop= - covener

13

如果你奔跑

[Service]
Type=simple

你需要的是:RemainAfterExit=yes

或者使用forking:

[Service]
Type=forking

我之前使用了“简单”选项,但是应用程序一直在开启和关闭,没有任何作用。当我插入了RemainAfterExist=yes后,它才真正运行起来。感谢@xsor! - pauljohn32

0

只需添加:RemainAfterExit=yes 就像魔法般的运行


2
不是一个好主意,因为如果进程被杀死(而不是停止),它仍然会显示为正在运行:RemainAfterExit = 接受布尔值,指定即使所有进程退出,服务是否仍应被视为活动状态。默认为否。 - Emil Burzo
嗨,sylvek。感谢您的回答。显然有一个非常相似的答案,但更完整:https://dev59.com/710a5IYBdhLWcg3wLV4G#39969975 如果您不想被其他人投反对票,我建议您删除此答案(通常情况下,您也会赢得一个徽章,至少第一次)。 - Valerio Bozz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接