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

为何关闭SSH连接后pm2 logs进程仍持续运行?

问题描述

我用这段bash脚本通过SSH查看服务器上的pm2日志:

ssh user@hostname source ./activate-node-env.sh && pm2 logs my-app

脚本运行正常,日志会像tail -f一样持续输出,我按Ctrl+C退出。但最近发现服务器上残留了大量pm2 logs进程:

ps ax | grep node
 1509 ?        Ssl    8:18 node /root/.nvm/versions/node/v14.16.0/bin/pm2 logs my-app --lines 20
 4133 ?        Ssl    0:34 node /root/.nvm/versions/node/v14.16.0/bin/pm2 logs my-app --lines 20
 5369 ?        Ssl    8:15 node /root/.nvm/versions/node/v14.16.0/bin/pm2 logs my-app --lines 20
 7466 ?        Ssl    8:21 node /root/.nvm/versions/node/v14.16.0/bin/pm2 logs my-app --lines 20
 8408 ?        Ssl   19:37 node /root/.nvm/versions/node/v14.16.0/bin/pm2 logs my-app --lines 20

按Ctrl+C退出SSH会话时,pm2 logs进程并未终止,请问原因是什么?如何确保退出时进程被清理?

原因分析

核心问题出在命令执行逻辑和信号传递上:

  • 原命令的写法会让本地shell解析&&,实际是先通过SSH执行远程的source ./activate-node-env.sh,然后在本地执行pm2 logs my-app——这显然不符合你的预期,若实际是远程执行pm2 logs,则是因为命令拆分导致信号无法正确传递。
  • 即便命令在远程执行,当按Ctrl+C时,SIGINT信号可能没传递给pm2 logs进程:如果远程进程被放入后台进程组,或者SSH会话断开时未触发SIGHUP信号,进程会成为孤儿进程继续运行。
解决方法

1. 修正SSH命令的执行逻辑

将所有命令用引号包裹,确保在远程shell的同一个会话中执行:

ssh user@hostname 'source ./activate-node-env.sh && pm2 logs my-app'

这样Ctrl+C发送的SIGINT信号会直接传递给远程的pm2 logs进程,触发终止。

2. 强制分配伪终端确保信号传递

如果修正命令后仍有残留,给SSH加上-t参数,强制分配伪终端,让远程进程作为前台进程组接收信号:

ssh -t user@hostname 'source ./activate-node-env.sh && pm2 logs my-app'

-t参数会保证SSH会话断开时,前台进程收到SIGHUP信号并终止。

3. 清理已存在的残留进程

对于服务器上已有的pm2 logs残留进程,可批量终止:

ssh user@hostname 'pkill -f "pm2 logs my-app"'

内容的提问来源于stack exchange,提问作者bennlich

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 00:45:39