当某些后台进程仍在运行时,命令“退出”不起作用

时间:2018-08-17 10:13:53

标签: logging ssh background-process exit pm2

'exit'命令不适用于我的情况,我也不明白为什么:

ssh user@mysever <<'HEREDOC'
  echo "1. Running PM2 log..."
  pm2 log &
  echo "2. PM2 log is now in background"
  exit
  echo "3. Won't be here"
HEREDOC

echo "4. Out."

即使使用上面的“ exit”命令,我也无法终止ssh管道。

我可以看到第一个回声,第二个回声;当然没有第三回声;并卡住。我期望可以看到第四回波的行为。我必须按Ctrl + C,然后才能看到第四个回声。

2 个答案:

答案 0 :(得分:2)

简短的回答:您应该为pm2流程重定向标准的输入,输出和错误:

pm2 log < /dev/null > /dev/null 2>&1 &

这将防止远程ssh服务器在pm2退出之前将会话保持打开状态。

更长的答案:

ssh user@mysever <<'HEREDOC'
    ...
    pm2 log &

以这种方式运行ssh时,远程ssh服务器将启动远程用户的shell的副本来处理会话。为了中继远程会话的输入和输出,远程ssh服务器将分配TTY或一组管道。然后,它将TTY或管道设置为Shell进程的标准输入,输出和错误。

因此,在远程系统上,您具有TTY或一组将远程Shell进程连接到SSH服务器进程的管道。 Shell调用的任何命令都将继承TTY或管道集作为命令的标准输入等。(除非您使用Shell功能来重定向标准文件句柄)。

您可能认为ssh服务器将在远程shell进程退出时终止会话。但这不是事实。 ssh服务器在读取TTY或连接到会话标准输出的管道上的文件结束条件时终止会话。

在您的情况下,您正在远程系统上调用此pm2命令,并且该命令继承了远程会话的标准输出。只要该程序正在运行,远程ssh服务器就不会在标准输出管道上获得EOF,也不会终止会话。

解决方法是重定向pm2进程的输入,因此它不会继承连接到ssh服务器的标准句柄:

pm2 log < /dev/null > /dev/null 2>&1 &

如果要捕获输出,可以重定向到文件而不是/ dev / null。我认为仅标准输出重定向是绝对必要的,但是您也应该确保标准输入和错误重定向。

答案 1 :(得分:0)

找到了原因,ssh隧道等到stdout(EOF)终止,并且没有进程读取stdin。

ssh user@myserver <<HEREDOC

  #1. terminate stdout by piping to file
  #2. send to background so it won't read stdin
  pm2 log >log.txt 2>&1 &

  #when going with Bash pipe, end pipe by directing to file
  pm2 log | grep error >log.txt 2>&1 &
HEREDOC