systemd忽略启动服务时的返回码

我在编写一个简单守护进程的单元文件时遇到了这个问题。 当守护进程在启动时返回“1”时,systemd会忽略它,看起来守护进程已成功启动,而实际上已经死了。

例如,我有非常简单的shell脚本:

#!/bin/bash exit 1 

所以单元文件看起来像这样:

 [Unit] Description=test service After=syslog.target [Service] User=testuser Group=testuser ExecStart=/usr/local/bin/return1 [Install] WantedBy=multi-user.target 

试着开始,似乎没问题:

 # service testservice start # echo $? 0 

但实际上它已经死了

 # service testservice status ● testservice.service - test service Loaded: loaded (/etc/systemd/system/testservice.service; enabled) Active: failed (Result: exit-code) since Fri 2016-01-22 14:51:45 MSK; 1min 13s ago Process: 16416 ExecStart=/usr/local/bin/return1 (code=exited, status=1/FAILURE) Main PID: 16416 (code=exited, status=1/FAILURE) Jan 22 14:51:45 servername systemd[1]: Started test service. Jan 22 14:51:45 servername systemd[1]: testservice.service: main process exited, code=exited, status=1/FAILURE Jan 22 14:51:45 servername systemd[1]: Unit testservice.service entered failed state. 

看起来像systemd认为守护进程已成功启动,但稍后崩溃。

我试图通过将服务types更改为“分叉”和其他方法来解决这个问题 – 这在非零代码的情况下工作正常,但服务实际上是“简单的”,所以在成功启动的情况下,它只是停留并保持terminal忙。

我如何pipe理这种服务? 或者可能有必要修正守护进程代码中的东西?

OS debian 8 x64,systemd 215

为了让systemd检测进程是否成功启动,你必须使用Type=forking ,然后将你的进程Type=forking一个助手脚本,如果进程成功启动,检入脚本。 分叉systemd将等待ExecStart命令完成,它将检查其退出状态。

你应该像这样改变你的单元文件:

 [Unit] Description=test service After=syslog.target [Service] Type=forking User=testuser Group=testuser ExecStart=/usr/local/bin/fork_service [Install] WantedBy=multi-user.target 

并在/usr/local/bin/fork_service你应该有这样的东西:

 #!/bin/bash # Run your process in background /path/to/your_service & # Check if the services started successfully if ! kill -0 $! 2>/dev/null; then # Return 1 so that systemd knows the service failed to start exit 1 fi 

我在这里只是检查后台进程PID是否仍然有效,但你可以有任何你想要的检查。 唯一重要的是,如果进程成功启动,则此脚本以0退出,如果失败,则以非零值为正值。

另外你不必使用Bash来分叉一个进程,你可以使用任何你想要的语言。