如何通过systemctl向自定义守护进程/服务发送SIGINT信号
我有一个希望在Linux机器上作为服务运行的脚本,命名为my_script.sh,它具备可执行权限,可通过./path/to/my_script.sh启动。
我还编写了一个终止my_script.sh的脚本kill_my_script.sh,其内容如下:
#!/bin/bash sudo kill -SIGINT $(pgrep my_script)
该脚本本质上是模拟对my_script.sh执行Ctrl+C操作。
在终端中运行这些脚本时一切正常:在ttyX中启动my_script.sh,在ttyY中执行kill_my_script.sh可触发其正常关闭流程。
为将其作为守护进程运行,我创建了/etc/systemd/system/my_script.service文件,内容如下:
[Unit] .... [Service] Type=simple User=root WorkingDirectory=/path/to/dir/ ExecStart=/path/to/my_script.sh ExecStop=/path/to/kill_my_script.sh Restart=on-failure [Install] ...
使用sudo systemctl start my_script.service可正常启动服务,但执行sudo systemctl stop my_script.service时,虽然触发了my_script.sh的关闭流程,却无法让它完成(关闭流程约需10秒),请问我遗漏了什么配置?
你需要补充关键配置并优化停止逻辑,具体如下:
1. 替换ExecStop逻辑,精准定位进程
不需要单独的kill_my_script.sh脚本,直接利用systemd内置的$MAINPID变量定位服务主进程,替换ExecStop配置:
ExecStop=/bin/kill -SIGINT $MAINPID
这样能精准向服务的主进程发送SIGINT信号,避免pgrep可能带来的误杀问题,同时去掉不必要的sudo(服务已以root身份运行)。
2. 添加停止超时等待配置
systemd默认会在触发停止操作后等待进程退出,但如果你的脚本关闭需要10秒,需明确设置超时时间,确保systemd不会提前强制终止进程:
TimeoutStopSec=15
将值设置为比实际关闭流程稍长的时间(比如15秒),给脚本足够的完成关闭操作的缓冲时间。
最终[Service]段示例
[Service] Type=simple User=root WorkingDirectory=/path/to/dir/ ExecStart=/path/to/my_script.sh ExecStop=/bin/kill -SIGINT $MAINPID TimeoutStopSec=15 Restart=on-failure
额外操作提示
修改service文件后,需要重新加载systemd配置并重启服务才能生效:
sudo systemctl daemon-reload sudo systemctl restart my_script.service
内容的提问来源于stack exchange,提问作者mxwQuestion

