我有一个 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);
}