我如何杀死一个中背景/分离SSH会话?
-
10-07-2019 - |
题
我使用的程序的协同作用与SSH隧道一起
它的工作原理,我只需要打开一个控制台型这两个命令:
ssh -f -N -L localhost:12345:otherHost:12345 otherUser@OtherHost
synergyc localhost
由于IM懒惰我提出其与一个鼠标点击一个图标运行击脚本:
#!/bin/bash
ssh -f -N -L localhost:12345:otherHost:12345 otherUser@OtherHost
synergyc localhost
与bash脚本上述工作为好,但现在我也想杀死协同效应,并通过一个鼠标点击的SSH隧道,所以我必须协同和ssh的PID保存到文件后,杀死他们:
#!/bin/bash
mkdir -p /tmp/synergyPIDs || exit 1
rm -f /tmp/synergyPIDs/ssh || exit 1
rm -f /tmp/synergyPIDs/synergy || exit 1
[ ! -e /tmp/synergyPIDs/ssh ] || exit 1
[ ! -e /tmp/synergyPIDs/synergy ] || exit 1
ssh -f -N -L localhost:12345:otherHost:12345 otherUser@OtherHost
echo $! > /tmp/synergyPIDs/ssh
synergyc localhost
echo $! > /tmp/synergyPIDs/synergy
但是,这脚本的文件是空的。
我如何获得SSH和协同的PID?点击
(I尽量避免ps aux | grep ... | awk ... | sed ...
组合,必须有更简单的方法。)
解决方案 5
以及我不想添加&在命令的端作为连接将死如果控制台wintow被关闭,所以,我结束了一个PS-的grep-AWK-沉渣 - 组合
ssh -f -N -L localhost:12345:otherHost:12345 otherUser@otherHost
echo `ps aux | grep -F 'ssh -f -N -L localhost' | grep -v -F 'grep' | awk '{ print $2 }'` > /tmp/synergyPIDs/ssh
synergyc localhost
echo `ps aux | grep -F 'synergyc localhost' | grep -v -F 'grep' | awk '{ print $2 }'` > /tmp/synergyPIDs/synergy
(你可以grep的融入awk的,但我现在懒得)
其他提示
<强>快速总结:不会工作强>
我的第一个想法是,你需要开始在后台流程来获得它们的PID与$!
。
像
一个图案some_program &
some_pid=$!
wait $some_pid
也许你需要什么......只是那么ssh将不会在前台索要密码短语了。
那么,你可能需要不同的东西毕竟。 ssh -f
可能产生一个新的进程的壳不能从无论如何调用它知道。理想情况下,SSH本身将提供一种方法,它的PID写入到某些文件。
使用所有尊重pgrep
,pkill
,ps | awk
等的用户,有一个的 多 强>更好的方法。
考虑,如果你依靠ps -aux | grep ...
找到你运行碰撞风险的过程。你可能有一个使用情况下这是不可能的,但作为一般规则,它不是要走的路。
SSH提供用于管理和控制的后台进程的机制。但像这么多的东西SSH,这是一个“高级”的功能,许多人(看来,从这里其他的答案),不知道它的存在。
在我自己用的情况下,我家里有一台工作站上,我要离开,在我的办公室连接到HTTP代理的内部网络上的隧道,另一个是让我快速访问管理界面上的合作 - 位于服务器。这是你如何可以创建基本的隧道,从家开始:
$ ssh -fNT -L8888:proxyhost:8888 -R22222:localhost:22 officefirewall
$ ssh -fNT -L4431:www1:443 -L4432:www2:443 colocatedserver
这些原因ssh来背景本身,而使隧道打开。但是,如果隧道消失了,我卡住了,如果我想找到它,我有我的分析进程列表和家庭我已经得到了“正确”的SSH(万一我不小心推出多种那些看起来相似)。
相反,如果我想管理多个连接,我用SSH的ControlMaster
配置选项,与控制-O
命令行选项一起。例如,在我的~/.ssh/config
文件下面,
host officefirewall colocatedserver
ControlMaster auto
ControlPath ~/.ssh/cm_sockets/%r@%h:%p
ssh的上述命令,在运行时,将离开斯普尔在~/.ssh/cm_sockets/
然后可以提供一种用于控制访问,例如:
$ ssh -O check officefirewall
Master running (pid=23980)
$ ssh -O exit officefirewall
Exit request sent.
$ ssh -O check officefirewall
Control socket connect(/home/ghoti/.ssh/cm_socket/ghoti@192.0.2.5:22): No such file or directory
和在这一点上,隧道(并且控制SSH会话)消失了,而不需要使用锤子(kill
,killall
,syngergyc
等)。
将这一回你的用例...
您正在建立希望通过其syngergys
交谈-L
TCP端口12345对于在隧道上,我会做一些像下面这样。
条目添加到您的LocalForward
文件:
Host otherHosttunnel
HostName otherHost
User otherUser
LocalForward 12345 otherHost:12345
RequestTTY no
ExitOnForwardFailure yes
ControlMaster auto
ControlPath ~/.ssh/cm_sockets/%r@%h:%p
请注意,命令行-f
选项与ExitOnForwardFailure
关键字处理,并且被包括在控制{万事达,路径}线,以确保您有控制在建立隧道之后。
然后,你可以修改你的bash脚本是这样的:
#!/bin/bash
if ! ssh -f -N otherHosttunnel; then
echo "ERROR: couldn't start tunnel." >&2
exit 1
else
synergyc localhost
ssh -O exit otherHosttunnel
fi
在else
选项背景隧道,留下一个插座上你了ControlPath以后关闭隧道。如果SSH失败(这可能是由于网络错误或LocalCommand
),没有必要退出隧道,但如果没有失败(synergyc
),synergyc表示启动,然后在隧道后关闭退出。
您可能还需要在看有无SSH选项<=>可以用来发动<=>从右侧内你的ssh配置文件。
正好碰到这个线程,想要提“的pidof” Linux工具:
$ pidof init
1
可以使用lsof的显示监听本地主机端口12345的处理的PID:
lsof -t -i @localhost:12345 -sTCP:listen
示例:
PID=$(lsof -t -i @localhost:12345 -sTCP:listen)
lsof -t -i @localhost:12345 -sTCP:listen >/dev/null && echo "Port in use"
您可以删除-f
,这使得它在后台运行它,然后用eval
运行它,它强制后台自己。
可以然后抓住pid
。确保把&
语句中<=>。
eval "ssh -N -L localhost:12345:otherHost:12345 otherUser@OtherHost & "
tunnelpid=$!
这是更为synergyc表示(以及试图守护进程自己最其他程序)的特殊情况。使用$!会工作,但不会synergyc表示执行过程中的clone()系统调用,这将赋予它新的PID除此之外庆典认为它有一个。如果要解决这个问题,这样就可以使用$!那么您可以告诉synergyc表示留在于地面,然后它的背景。
synergyc -f -n mydesktop remoteip &
synergypid=$!
synergyc表示还做了一些其他的东西一样,你可能要关闭,如果你想管理它自动重启。
另一种选择是使用p纤ep找到最新的ssh进程的PID
ssh -fNTL 8073:localhost:873 otherUser@OtherHost
tunnelPID=$(pgrep -n -x ssh)
synergyc localhost
kill -HUP $tunnelPID
您可以看出来的绑定到你的本地端口的SSH proceess,使用该行:
netstat -tpln | grep 127\.0\.0\.1:12345 | awk '{print $7}' | sed 's#/.*##'
它返回使用本地主机端口12345 / TCP过程的PID。所以,你不必过滤从ssh
。
ps
结果
如果你只需要检查,的如果的端口绑定,使用:
netstat -tln | grep 127\.0\.0\.1:12345 >/dev/null 2>&1
返回1
如果没有结合或0
如果有人正在侦听到该端口。
,这里是一个简单的脚本(测试)利用的 SSH控制插座的,无需额外配置的:
#!/bin/bash
if ssh -fN -MS /tmp/mysocket -L localhost:12345:otherHost:12345 otherUser@otherHost; then
synergyc localhost
ssh -S /tmp/mysocket -O exit otherHost
fi
synergyc
将仅如果隧道已经成功建立开始,这本身将尽快返回<=>被关闭。
尽管该解决方案缺乏适当的错误报告。