如何在SSH中获取最后一个后台进程的pid



我的shell脚本是这样通过SSH运行的:

ssh -i mycert.pem testuser@myserver.com <<SSHBLOCK
pm2 logs --lines 100 &
pid=$!
sleep 3
kill $pid
SSHBLOCK

该脚本在本地服务器上按预期工作(未包装在 ssh 块中(。但是当我需要在远程服务器上获取日志时,$pid只是空白的。为什么是$!在上面的 SSH 块中使用时为空?

这是因为本地 shell(您用来运行ssh的 shell (将尝试扩展$!

将 here doc 分隔符放入单引号以避免局部变量扩展:

ssh -i mycert.pem testuser@myserver.com << 'SSHBLOCK'
pm2 logs --lines 100 &
pid=$!
sleep 3
kill $pid
SSHBLOCK

https://www.gnu.org/software/bash/manual/html_node/Redirections.html#Here-Documents

当您在本地运行它时,您的 shell 会$!扩展到最后一个背景 pid,如您所料。但是,在您编写时,包括$!在内的变量是由运行ssh命令的 shell 展开的,而不是由远程主机扩展的。

将您的 heredoc 想象成类似于双引号:

ssh user@host "pm2 logs --lines 100 & pid=$!; sleep 3; kill $pid"

这里的$!扩展到最后一个背景 pid ...的本地外壳。

解决此问题的最简单方法可能是转义$字符或单引号您的 heredoc 标记以避免变量扩展。另一种选择是将整个"脚本"放入单引号中:

ssh -i mycert.pem testuser@myserver.com '
pm2 logs --lines 100 &
pid=$!
sleep 3
kill $pid'

你得到这个问题是因为你混合了局部变量和远程变量。

当你写 :

pid=$!
sleep 3
kill $pid

您尝试读取本地客户端上使用的最后一个 PID。

你应该写:

pid="$!"
sleep 3
kill "$pid"

以获取远程值。

或者,如果您只使用远程变量,则可以引用您的 heredoc :

ssh -i mycert.pem testuser@myserver.com <<'SSHBLOCK'
pm2 logs --lines 100&
pid=$!
sleep 3
kill $pid
SSHBLOCK

最新更新