systemd:启动后立即出现 SIGTERM

systemd: SIGTERM immediately after start

我是第一次尝试 systemd。我想在系统启动时启动一个进程。我在启动和 运行ning 时遇到问题。

systemd 应该 运行 一个脚本 (start.sh)。该脚本在后台启动一个进程(我们称之为 P)并以代码 0 退出。 P 一直保持 运行ning 直到信号发生。

如果我运行 start.sh 手动都可以。

如果我让它由 systemd 启动,P 在启动后立即收到 SIGTERM 并终止。

所以它开始了,但是信号呢?? 它终止了 P,我不确定它的起源和原因是什么。

也许我的单位不对,但我不知道如何设置它以满足我的需要。 我尝试了服务类型简单、空闲和一次性。

感谢您的帮助! 克里斯

这是我的单位。

[Unit]
Description=Test
After=sshd.service

[Service]
Type=oneshot
ExecStart=/home/max/start.sh start
Restart=no
User=root
SuccessExitStatus=0

[Install]
WantedBy=multi-user.target

这就是状态。

Loaded: loaded (/etc/systemd/system/test.service; enabled)
Active: inactive (dead) since Die 2016-02-23 20:56:59 CET; 20min ago
Process: 1046 ExecStart=/home/max/test.sh start (code=exited, status=0/SUCCESS)

当 start.sh 完成时,systemd 将杀死与 start.sh

相同的 cgroup 中的所有内容

您的选择是:

  • 在Unit部分设置KillMode进行处理(默认为control-group)。这将导致 systemd 仅终止它直接触发的进程。

  • 不要让 start.sh 在后台启动并退出,而是在前台执行它

我认为在您的情况下,选项 2 可行且更直接。

来源:https://unix.stackexchange.com/a/231201/45329

尽管像下面这样将 KillMode 更改为 process 将适用于您的情况,但这不是推荐的解决方案。

[Service]
KillMode=process
...

KillMode 设置为 process 的问题是 systemd 失去了对其启动进程的所有子进程的控制。这意味着,如果发生任何事情并且您的进程之一没有因为某种原因而死,它将继续徘徊。

根据您的情况,更好的解决方案是创建所有进程,keep their pid and then wait 在它们上面。

您在 shell 脚本中使用的等待命令可能会有所不同,具体取决于您使用的 shell(我建议的 link 用于 bash)。让 shell 脚本等待所有子级实际上与在前台启动一个未分离的子级相同。

大概是这样的:

#!/bin/bash

# Start your various processes
process1 &
PROCESS1_PID=$!
process2 &
PROCESS2_PID=$!
process3 &
PROCESS3_PID=$!

# Wait on your processes
wait $PROCESS1_PID $PROCESS2_PID $PROCESS3_PID

# OR, if I'm correct, bash also allows you to wait on all children
# with just a plain wait like so:
wait

# reach here only after children 1, 2, and 3 died