我的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