Linux 检查SSH隧道是否已启动并正在运行

Linux 检查SSH隧道是否已启动并正在运行,linux,perl,telnet,ssh-tunnel,Linux,Perl,Telnet,Ssh Tunnel,我有一个perl脚本,当有点失败时,它看起来像这样: my $randport = int(10000 + rand(1000)); # Random port as other scripts like this run at the same time my $localip = '192.168.100.' . ($port - 4000); # Don't ask... backwards compatibility system("ssh -NL $randpor

我有一个perl脚本,当有点失败时,它看起来像这样:

my $randport = int(10000 + rand(1000));          # Random port as other scripts like this run at the same time
my $localip = '192.168.100.' . ($port - 4000);   # Don't ask... backwards compatibility
system("ssh -NL $randport:$localip:23 root\@$ip -o ConnectTimeout=60 -i somekey &");    # create the tunnel in the background

sleep 10;       # Give the tunnel some time to come up

# Create the telnet object
my $telnet = new Net::Telnet(
        Timeout =>      10,
        Host    =>      'localhost',
        Port    =>      $randport,
        Telnetmode =>   0,
        Errmode =>      \&fail,
);

# SNIPPED... a bunch of parsing data from $telnet
问题是,目标$ip位于带宽不可预测的链路上,因此隧道可能会立即出现,可能需要一段时间,可能根本不会出现。因此,睡眠是必要的,给隧道一些时间起床和运行

所以问题是:我如何测试隧道是否正常运行?如果隧道直接到达,10秒是一个非常不受欢迎的延迟。理想情况下,我希望检查它是否启动,并在启动后继续创建telnet对象,最长为30秒

编辑:Ping没有帮助我移动,因为隧道的远端通常是向上的,但是有非常高的包丢失量

已解决:根据mikebabcock建议的提示推断,
sleep 10
已替换为此块,其效果类似于符咒:

my $starttime = time();
while (1)
{
    # Check for success
    if (system("nc -dzw10 localhost $randport > /dev/null") == 0) { last }

    # Check for timeout
    if (time() > $starttime + 30) { &fail() }

    # 250ms delay before recheck
    select (undef, undef, undef, 0.25);
}

您可以将ping集成到ssh服务器中,如果工作正常,ssh隧道就启动了

# only a ping sample :-D
if !  ping -c 1 192.168.101.9
then
        echo ":-("
else
        echo ":-)"
fi

我认为fping可能比通常的ping更好,脚本更友好

fping-t 60000[您的服务器]

应在放弃前60秒尝试连接到服务器 差不多

if(fping -t 60000 [your server]) {
execute desired code;
} else {
execute this script again to rerun;;
}
即使编码不是真的,我想你也会明白这一点。

在Linux系统上使用netcat——通常
nc

nc -dvzw10 ${HOSTNAME} 23
对我来说很有效,回答如下:

Connection to ${HOSTNAME} 23 port [tcp/telnet] succeeded!
如果成功,它也会返回0,并对一个简单的连接感到满意,然后它就会离开

  • -d表示不从键盘侧读取任何内容
  • -v表示冗长(在脚本中关闭此选项)
  • -z表示连接后断开连接
  • -w10表示最多等待10秒,否则放弃

ping对我没有多大帮助,因为它通常有约50%的包装损耗(这是事先测试的,信不信由你,可以降低到50%),但如果隧道打开,它会成功退出。质量是其他通信级别的一部分。如果希望等待更好的质量,可以解析ping输出。但是如果质量太差,您会断开连接吗?因为您使用的是
Net::Telnet
模块,您是否尝试过使用
open
调用并测试成功?我不是Telnet专家,但如果是我,我可能会尝试这样做……如果没有一种简单的测试方法,我可能会这样做:如果尝试时间<30秒,则重试直到成功