简体   繁体   English

Systemd + Sys V init.d脚本:启动有效,但停止无效

[英]Systemd + Sys V init.d script: start works, but stop does not

I'm pretty new to writing systemd compatible init scripts. 我对编写与systemd兼容的初始化脚本很陌生。 I've tried the following example: 我尝试了以下示例:

#!/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 "$1" 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

So far, so good. 到现在为止还挺好。 Now, I install the init script like so: 现在,我像这样安装init脚本:

update-rc.d test defaults
update-rc.d test enable

Again, so far, so good. 再一次,到目前为止,很好。 I've setup this init script specifically to fail (I had to do so during my testing to confirm the issue I was having.) 我已经将这个初始化脚本专门设置为失败(我在测试期间必须这样做以确认我遇到的问题。)

If I run /etc/init.d/test start, it fails as expected, and I can see the error message in my log. 如果我运行/etc/init.d/test start,它会按预期失败,并且我可以在日志中看到错误消息。

If, however, I run /etc/init.d/test stop, I get nothing in my log, and the script returns successfully. 但是,如果我运行/etc/init.d/test stop,则日志中什么也没有,脚本成功返回。

It seems like systemd is doing some kind of black magic behind the scenes and is hijacking stop somehow, but I can't figure out how, and I've been Googling around forever without success. 似乎systemd在幕后进行某种黑魔法并以某种方式劫持,但我不知道怎么做,而且我一直在谷歌搜索中一直没有成功。 Can anyone help me to understand why passing stop to my init script doesn't execute the corresponding code in my case block? 谁能帮助我了解为什么在我的case块中传递stop到我的初始化脚本不执行相应的代码?

As a side note, the status option also doesn't work (systemd just outputs its own status info.) 附带说明,状态选项也不起作用(systemd仅输出其自己的状态信息。)

I'm attempting to run this on Ubuntu 16.04. 我正在尝试在Ubuntu 16.04上运行它。 Thank you! 谢谢!

You'll notice the top of your script loads /lib/lsb/init-functions . 您会注意到脚本的顶部加载了/lib/lsb/init-functions You can read the code in there and the related code in /lib/lsb/init-functions.d to understand the related code you are pulling in. 您可以阅读其中的代码以及/lib/lsb/init-functions.d的相关代码,以了解要插入的相关代码。

A summary is that your script likely being converted to a systemd .service in the background and is subject to a whole host of documented incompatibilities with systemd 一个总结是,您的脚本可能会在后台转换为systemd .service ,并且可能会受到大量已记录的与systemd不兼容的记录

There is inherit extra complexity and potential problems when you ask systemd to emulate and support the file formats used by the legacy Upstart and sysVinit init systems. 当您要求systemd模拟和支持旧版UpstartsysVinit初始化系统使用的文件格式时,会带来额外的复杂性和潜在的问题。

Since you are writing new init script from scratch, consider writing a systemd .service file directly, removing all the additional complexity of involving additional init systems. 由于您是从头开始编写新的初始化脚本,请考虑直接编写systemd .service文件,从而消除了涉及其他初始化系统的所有其他复杂性。

A minimal .service file to go in /etc/systemd/system/ could look like: 放在/etc/systemd/system/的最小.service文件如下所示:

[Unit]
Description=Foo

[Service]
ExecStart=/usr/sbin/foo-daemon

[Install]
WantedBy=multi-user.target

More details in man systemd.service . 有关更多详细信息,请参见man systemd.service Some additional learning now will save you some debugging later! 现在进行一些额外的学习将为您节省以后的调试工作!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM