我的shell脚本以这种方式通过SSH运行:
ssh -i mycert.pem testuser@myserver.com <<SSHBLOCK
pm2 logs --lines 100 &
pid=$!
sleep 3
kill $pid
SSHBLOCK
在本地服务器上(未包装在ssh块中),脚本按预期工作。但是当我需要在远程服务器上获取日志时,$ pid只是空白。为什么是$!在上面的SSHBLOCK中使用时为空?
答案 0 :(得分:2)
那是因为本地shell(用于运行[code]
import os
os.system('net use w: /delete')
os.system('net use w: \\\\apps\\NotesFolder')
[/code]
的shell)将尝试展开ssh
。
将此doc doc delimiter放入单引号中以避免局部变量扩展:
$!
https://www.gnu.org/software/bash/manual/html_node/Redirections.html#Here-Documents
答案 1 :(得分:2)
当您在本地运行它时,您的shell会将$!
扩展为最后一个背景pid,如您所料。但是,正如您所编写的那样,包含$!
的变量正由运行ssh
命令的shell扩展,而不是由远程主机扩展。
将您的heredoc视为类似于双引号:
ssh user@host "pm2 logs --lines 100 & pid=$!; sleep 3; kill $pid"
此处$!
扩展到本地shell的最后一个背景pid ....
解决此问题的最简单方法可能是逃避$
字符或单引号heredoc标记以避免变量扩展。还有一个选择是将整个&#34;脚本&#34;单引号:
ssh -i mycert.pem testuser@myserver.com '
pm2 logs --lines 100 &
pid=$!
sleep 3
kill $pid'
答案 2 :(得分:1)
您遇到此问题是因为您混合了本地和远程变量。
当你写:
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