You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 21:30:52