我想要创建一个Linux (bash-)脚本,它创建一个SSH隧道,运行一个使用该隧道的本地命令,最后关闭隧道和周围的SSH连接。
为了减少解释这一问题的难度,可以考虑将本地SSH配置配置为一个名为“remoteserver”的主机,其中包含没有密码的本地私钥,因此
ssh remoteserver -L 4444:targetserver:5555
将直接打开到远程服务器的连接,并创建从本地端口4444到目标服务器的隧道。如果本地命令是localclient --port 4444,那么在本地客户端应用程序完成后,打开隧道、执行本地命令和关闭隧道的脚本会是什么样的呢?
由于应该可以保持其他并行的正在进行的SSH连接,所以我不想要类似于sudo killall ssh的东西。
发布于 2013-10-19 18:43:03
你可以尝试这样的方法
TIMEOUT=60 # seconds
ssh remoteserver -L 4444:targetserver:5555 sleep $TIMEOUT &
localclient --port 4444隧道将在$TIMEOUT秒后自动关闭。请注意,使用&只对无密码连接有效。否则,您需要使用SSH的-f标志。
或者,
ssh -N remoteserver -L 4444:targetserver:5555 &
sshpid=$!
localclient --port 4444
kill $sshpid会在localclient执行后杀死隧道。请注意,这将不适用于-f标志,因为进程是双叉的。
发布于 2016-09-04 13:04:17
ssh-only解决方案(对我不起作用)
@damienfrancois的第二个建议是直白的,但出于某种原因,我不喜欢不得不kill某物的想法。
而且,我不敢相信ssh没有这方面的内置机制。的确如此。事情应该是这样运作的:
ssh remoteserver -o "PermitLocalCommand yes" -o "LocalCommand localclient --port 4444" \
-L 4444:targetserver:5555 -N但出于某种原因,这并不像我所期望的那样有效:我首先尝试了一些简单的东西,比如用于LocalCommand的LocalCommand,但是-N使命令挂起,所以我使用了sleep 0,这看起来很有效。
但是当我插入实际的网络命令时,结果运行得非常慢。它不是在不到1秒的时间内完成,而是花了40秒才出现开始消息。我在20分钟后终止了命令。
管道解决方案(对我有用)
经过一些实验之后,我现在使用的是:
ssh remoteserver -L 4444:targetserver:5555 keepalive.sh \
| (sleep 0.5; localclient --port 4444)远程端的keepalive.sh是这样的:
while true; do
sleep 1
echo "keepalive"
donesleep 0.5需要(某种程度上)确保隧道是在localclient启动之前设置的(对于一个遥远或缓慢的remoteserver,您可能需要更长的等待时间)。一旦localclient完成,隧道就会终止,因为当第二个命令关闭其标准输入时,shell就会终止管道。
这比达米恩弗朗索瓦的解决方案好吗?视情况而定。
对keepalive.sh的需求是一个明显的缺点,但是不管localclient终止的方式和原因如何,清除隧道的方式都是更干净的。
我需要在Makefile上下文中这样做,就像它适合于一行的事实一样。
https://stackoverflow.com/questions/19469501
复制相似问题