Systemd + Sys V init.d 脚本:启动有效,但停止无效
Systemd + Sys V init.d script: start works, but stop does not
我对编写与 systemd 兼容的初始化脚本还很陌生。我尝试了以下示例:
#!/bin/sh
#
### BEGIN INIT INFO
# Provides: test
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Test.
# Description: Test.
### END INIT INFO
#
# Define LSB log_* functions.
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
. /lib/lsb/init-functions
case "" in
stop)
log_failure_msg "Stop!"
exit 1
;;
start)
log_failure_msg "Start!"
exit 1
;;
restart)
log_failure_msg "Restart!"
exit 1
;;
status)
log_failure_msg "Status!"
exit 1
;;
*)
echo "Usage: $SELF start|stop|restart|status"
exit 1
;;
esac
# Some success paths end up returning non-zero, so exit 0 explicitly. See bug #739846.
exit 0
到目前为止,还不错。现在,我像这样安装初始化脚本:
update-rc.d test defaults
update-rc.d test enable
同样,到目前为止,一切都很好。我已将此初始化脚本专门设置为失败(我在测试期间必须这样做以确认我遇到的问题。)
如果我 运行 /etc/init.d/test 启动,它会按预期失败,我可以在我的日志中看到错误消息。
但是,如果我 运行 /etc/init.d/test 停止,我的日志中什么也没有,并且脚本 returns 成功。
似乎 systemd 正在幕后施展某种黑魔法,以某种方式劫持停止,但我不知道是如何做到的,而且我一直在谷歌搜索,但一直没有成功。谁能帮我理解为什么将 stop 传递给我的 init 脚本不会在我的 case 块中执行相应的代码?
附带说明一下,状态选项也不起作用(systemd 仅输出其自己的状态信息。)
我正尝试 运行 在 Ubuntu 16.04 上进行此操作。谢谢!
您会注意到脚本的顶部已加载 /lib/lsb/init-functions
。你可以阅读那里的代码和/lib/lsb/init-functions.d
中的相关代码来了解你拉入的相关代码。
总结一下,您的脚本可能在后台转换为 systemd
.service
,并且受制于 whole host of documented incompatibilities with systemd
当您要求 systemd 模拟和支持遗留 Upstart
和 sysVinit
初始化系统使用的文件格式时,会继承额外的复杂性和潜在问题。
由于您是从头开始编写新的初始化脚本,请考虑直接编写 systemd
.service
文件,从而消除涉及其他初始化系统的所有额外复杂性。
要放入 /etc/systemd/system/
的最小 .service
文件可能如下所示:
[Unit]
Description=Foo
[Service]
ExecStart=/usr/sbin/foo-daemon
[Install]
WantedBy=multi-user.target
man systemd.service
中有更多详细信息。现在一些额外的学习将为您节省一些调试时间!
我对编写与 systemd 兼容的初始化脚本还很陌生。我尝试了以下示例:
#!/bin/sh
#
### BEGIN INIT INFO
# Provides: test
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Test.
# Description: Test.
### END INIT INFO
#
# Define LSB log_* functions.
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
. /lib/lsb/init-functions
case "" in
stop)
log_failure_msg "Stop!"
exit 1
;;
start)
log_failure_msg "Start!"
exit 1
;;
restart)
log_failure_msg "Restart!"
exit 1
;;
status)
log_failure_msg "Status!"
exit 1
;;
*)
echo "Usage: $SELF start|stop|restart|status"
exit 1
;;
esac
# Some success paths end up returning non-zero, so exit 0 explicitly. See bug #739846.
exit 0
到目前为止,还不错。现在,我像这样安装初始化脚本:
update-rc.d test defaults
update-rc.d test enable
同样,到目前为止,一切都很好。我已将此初始化脚本专门设置为失败(我在测试期间必须这样做以确认我遇到的问题。)
如果我 运行 /etc/init.d/test 启动,它会按预期失败,我可以在我的日志中看到错误消息。
但是,如果我 运行 /etc/init.d/test 停止,我的日志中什么也没有,并且脚本 returns 成功。
似乎 systemd 正在幕后施展某种黑魔法,以某种方式劫持停止,但我不知道是如何做到的,而且我一直在谷歌搜索,但一直没有成功。谁能帮我理解为什么将 stop 传递给我的 init 脚本不会在我的 case 块中执行相应的代码?
附带说明一下,状态选项也不起作用(systemd 仅输出其自己的状态信息。)
我正尝试 运行 在 Ubuntu 16.04 上进行此操作。谢谢!
您会注意到脚本的顶部已加载 /lib/lsb/init-functions
。你可以阅读那里的代码和/lib/lsb/init-functions.d
中的相关代码来了解你拉入的相关代码。
总结一下,您的脚本可能在后台转换为 systemd
.service
,并且受制于 whole host of documented incompatibilities with systemd
当您要求 systemd 模拟和支持遗留 Upstart
和 sysVinit
初始化系统使用的文件格式时,会继承额外的复杂性和潜在问题。
由于您是从头开始编写新的初始化脚本,请考虑直接编写 systemd
.service
文件,从而消除涉及其他初始化系统的所有额外复杂性。
要放入 /etc/systemd/system/
的最小 .service
文件可能如下所示:
[Unit]
Description=Foo
[Service]
ExecStart=/usr/sbin/foo-daemon
[Install]
WantedBy=multi-user.target
man systemd.service
中有更多详细信息。现在一些额外的学习将为您节省一些调试时间!