Mam skrypt Perla, który po destylowanej trochę, wygląda tak:Sprawdzanie, czy tunel SSH jest uruchomiony
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
Chodzi o to, że cel $ ip jest na link z bardzo nieprzewidywalny przepustowość, więc tunel może pojawić się od razu, może to chwilę potrwać, może nie pojawić się wcale. Więc sen jest konieczny, aby dać tunelowi trochę czasu na rozpoczęcie pracy.
Pytanie brzmi: Jak mogę sprawdzić, czy tunel jest uruchomiony? 10 sekund to naprawdę niepożądane opóźnienie, jeśli tunel natychmiast się podniesie. Idealnie chciałbym sprawdzić, czy jest włączony i kontynuować tworzenie obiektu telnetu, gdy jest, maksymalnie do, powiedzmy, 30 sekund.
Edit: Ping nie pomaga mi Mouch, jak zdalny koniec tunelu jest zwykle, ale z bardzo dużą ilością packetloss
rozwiązany: ekstrapolację od czubka sugerowanej przez Mike Babcock , sleep 10
został zastąpiony tego bloku, który działa jak czar:
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);
}
Od kiedy używasz modułu 'Net :: Telnet', czy próbowałeś użyć wywołania' open' i testowania, aby odnieść sukces? Nie jestem ekspertem od Telnet, ale prawdopodobnie spróbowałbym, gdyby to ja ... –
Mogę to zrobić, jeśli nie ma prostego sposobu testowania: spróbuj ponownie, aż powodzenie, jeśli time_spend_trying <30 sekund – Jarmund