我有一个脚本需要到远程服务器的隧道。像这样的东西:
ssh -fNL 8080:localhost:80 my_server
我怎样才能关闭隧道后本地脚本结束?
上面的例子只是我尝试过的组合之一。我已经了解了如何进行阻塞 ssh 调用、执行远程命令以及使用“睡眠”自动关闭隧道,但我只想要一种仅在脚本执行期间提供隧道的方法。
我的最后一个方法是将 ssh 分叉到后台,并在脚本终止时让它被杀死,但使用上述命令,ssh 进程在结束脚本后仍然存在。我也在探索如何获取PID来手动杀死后台ssh。
答案1
只需使用
function atexit() {
kill $TUNNEL_PID
}
trap atexit EXIT
ssh -nNL 8080:localhost:80 my_server &
TUNNEL_PID=$!
(即,不要告诉 ssh 本身到后台,只需将其作为常规后台任务运行并保存 pid)
答案2
您应该能够通过&
在末尾添加来将 ssh 命令设置为后台。然后,在下一行添加
SSHPID=$!
$!是最近的后台命令的 PID,因此它是 SSH 会话的 PID。然后,在脚本的末尾,只需kill -SIGKILL $SSHPID
.
答案3
刚刚测试了一个解决方案,我不喜欢它的完成方式,但它有效:
先决条件:
- 已安装屏幕命令
- 使用已解锁的 ssh 密钥进行 ssh 连接
关于如何构建解决方案的说明:
添加到以下需要启动隧道的行:
screen -d -m -S myTunnel ssh 0.0.0.0:123:118.218.118.218:5555 myServer # starts a screen in detached mode and create your tunnel
运行您的操作并将其添加到脚本的末尾:
kill `ps -A -o -pid,cmd|grep "SCREEN -d -m -S myTunnel"| grep -v grep| head -n 1| awk '{print $1}'` # kills the opened screen
screen -wipe # clears screens list (not allways usefull, depends on the commands ran by the screen)
隧道现已关闭。
这个解决方案有效(刚刚测试过),但这不是最先进的答案。
编辑:我确信会有更好的答案