Ubuntu22.04中systemd执行shell脚本启动Node进程无法随服务终止求助
解决Ubuntu 22.04中systemd通过shell脚本运行Snap版Node.js时进程无法终止的问题
当你用shell脚本作为systemd服务的ExecStart目标时,systemd实际跟踪的是shell进程而非Node.js进程。停止服务时,systemd仅向shell进程发送终止信号,但默认情况下shell不会将信号转发给它启动的Node子进程,导致Node进程残留,再次启动时因端口占用等问题失败。而直接在ExecStart中执行Node命令时,systemd直接管理Node进程,信号能正常传递,所以进程可随服务终止。
以下是两种可靠的解决方案:
方案1:用exec让Node进程替换Shell进程
修改你的shell脚本,使用exec命令启动Node,这样Shell进程会被Node进程替换,systemd直接跟踪Node进程,终止信号能直接传递给Node:
#!/usr/bin/sh -x exec node /home/bariks/PeerJS/peerjs.server.js
方案2:在Shell脚本中捕获并转发终止信号
如果你的脚本需要执行启动前预处理(如环境变量配置、文件检查等),无法使用exec,可以在脚本中捕获终止信号并转发给Node进程:
#!/usr/bin/sh -x # 启动Node进程并后台运行,记录PID node /home/bariks/PeerJS/peerjs.server.js & NODE_PID=$! # 设置信号捕获,将TERM/INT信号转发给Node进程 trap "kill $NODE_PID" TERM INT # 等待Node进程结束,避免Shell提前退出 wait $NODE_PID
后续验证步骤
- 确保脚本拥有执行权限:
chmod +x /home/bariks/PeerJS/peerjs.sh
- 重新加载systemd配置并重启服务:
sudo systemctl daemon-reload sudo systemctl restart peerjs.service
- 验证停止服务后Node进程是否终止:
sudo systemctl stop peerjs.service ps aux | grep node
若输出中无对应Node进程,则说明问题解决。
内容的提问来源于stack exchange,提问作者Nadav Popplewell
相关产品推荐
相关产品推荐

