systemd: SIGTERM立即启动后
systemd: SIGTERM立即启动后
我第一次尝试使用systemd。我想在系统启动时启动一个进程。但是我在启动和运行过程中遇到了问题。\nsystemd应该运行一个脚本(start.sh)。这个脚本在后台启动一个进程(我们称之为P),然后以0的代码退出。\nP会一直运行,直到收到一个信号。\n如果我手动运行start.sh一切正常。\n但是如果我让systemd启动start.sh,P在启动后立即收到一个SIGTERM信号并终止。\n所以P是被启动了,但是信号呢?\n它终止了P,但是我不确定信号的来源和原因。\n也许我的unit设置有问题,但是我不知道怎么为我的需求进行设置。\n我尝试了service-type simple、idle和oneshot。\n谢谢帮助!\nChris\n这是我的unit。\n[Unit]\nDescription=Test\nAfter=sshd.service\n[Service]\nType=oneshot\nExecStart=/home/max/start.sh start\nRestart=no\nUser=root\nSuccessExitStatus=0\n[Install]\nWantedBy=multi-user.target\n
\n这是状态。\n
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)
问题出现的原因是将KillMode
设置为process
后,systemd
失去对启动的所有子进程的控制。这意味着,如果发生任何情况导致其中一个进程由于某种原因未能终止,它将继续存在。
解决方法是在启动所有进程后,获取它们的pid
,然后在它们上面使用wait
命令。具体使用的等待命令可能因使用的shell而有所不同(我提供的链接是针对bash的)。让脚本等待所有子进程实际上等同于在前台启动一个不会被分离的子进程。
示例代码如下:
#!/bin/bash # 启动各个进程 process1 & PROCESS1_PID=$! process2 & PROCESS2_PID=$! process3 & PROCESS3_PID=$! # 等待进程结束 wait $PROCESS1_PID $PROCESS2_PID $PROCESS3_PID # 或者,如果我没记错的话,bash也允许使用普通的wait等待所有子进程 wait # 在子进程1、2和3都终止后才执行以下代码
当start.sh完成时,systemd会杀死与start.sh处于同一cgroup中的所有进程。
您的选择有:
- 在Unit部分设置KillMode为process(默认为control-group)。这将导致systemd只杀死直接启动的进程。
- 不要使start.sh在后台启动某些东西并退出,而是在前台执行它。
我认为在您的情况下,选项2是可行且更直接的。
来源:https://unix.stackexchange.com/a/231201/45329
问题在于脚本需要启动多个进程。而且所有这些进程都是并行运行的。我尝试保持我的示例简单,所以没有提到这一点。