我使用的程序的协同作用与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写入到某些文件。

使用所有尊重pgreppkillps | 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会话)消失了,而不需要使用锤子(killkillallsyngergyc等)。

将这一回你的用例...

您正在建立希望通过其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如果有人正在侦听到该端口。

基于@ghoti的很好的答案

,这里是一个简单的脚本(测试)利用的 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将仅如果隧道已经成功建立开始,这本身将尽快返回<=>被关闭。 尽管该解决方案缺乏适当的错误报告。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top