我有一个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是一个带有非常不可预测的带宽的链路,所以隧道可能马上出现,可能需要一段时间,根本不可能出现。 所以睡觉是必要的,给隧道一些时间起床和运行。
所以问题是:如何testing隧道是否正常运行? 如果隧道直接出现,10秒钟是非常不理想的延迟。 理想情况下,我想检查它是否已经启动,并继续创build一次telnet对象,最长时间为30秒。
编辑:平不帮我勉强,因为隧道的远端是普遍的,但有很高的数据包丢失
解决:从mikebabcockbuild议的提示推断, 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); }
使用netcat – 通常在Linux系统上是nc
:
nc -dvzw10 ${HOSTNAME} 23
对我来说,有一个回应如下:
Connection to ${HOSTNAME} 23 port [tcp/telnet] succeeded!
它也会在成功时返回0,并且在一个简单的连接之后就会很快乐。
你可以集成一个ping到你的ssh服务器,如果工作正常,那么ssh隧道就会启动
# only a ping sample :-D if ! ping -c 1 192.168.101.9 then echo ":-(" else echo ":-)" fi
我认为fping可能比平常更好,更友善的脚本。
fping -t 60000 [你的服务器]
应该尝试连接到服务器60秒之前放弃类似的东西
if(fping -t 60000 [your server]) { execute desired code; } else { execute this script again to rerun;; }
即使编码不是真实的,我想你也会明白。