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

标签 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 $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 位于带宽非常不可预测的链路上,因此隧道可能会立即出现,可能需要一段时间,也可能根本不会出现。因此, sleep 是必要的,以便让隧道有时间启动和运行。

所以问题是:如何测试隧道是否已启动并正在运行?如果隧道立即出现,10 秒是一个非常不受欢迎的延迟。理想情况下,我想检查它是否已启动,并在启动后继续创建 telnet 对象,最多持续 30 秒。

编辑: Ping 没有帮助我解决问题,因为隧道的远端通常正常运行,但丢包量非常高

已解决:根据 mikebabcock 建议的提示推断,sleep 10 已被替换为这个功能强大的 block :

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);
}

最佳答案

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

nc -dvzw10 ${HOSTNAME} 23

对我有用,响应如下:

Connection to ${HOSTNAME} 23 port [tcp/telnet] succeeded!

它也会在成功时返回 0,并且对一个简单的连接很满意,然后它就会消失。

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

关于linux - 检查 SSH 隧道是否已启动并正在运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12605197/

相关文章:

perl - 使用 readdir 时重命名文件是否安全?

perl - 如何使用 Perl 通过 Lotus Notes API 打开收件箱?

go - 如何从 Telnet session 读取数据

c - C 中的 fork 和 waitpid

linux - 在 linux CPU 负载中包含 glibtop

perl - 试图在 Perl 中将子目录作为参数传递

elixir - 如何编辑回显服务器以允许多个客户端交换消息

linux - 当用户按任意键时telnet发送哪些数据

c - 如何在Linux中获得正确的堆起始地址?

linux - 为 Red Hat Linux 构建的 Git 版本