2012-09-26 18 views
6

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

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 ... –

+0

Mogę to zrobić, jeśli nie ma prostego sposobu testowania: spróbuj ponownie, aż powodzenie, jeśli time_spend_trying <30 sekund – Jarmund

Odpowiedz

6

Zastosowanie netcat - często nc na systemach Linux:

nc -dvzw10 ${HOSTNAME} 23 

pracuje dla mnie, o reakcji typu:

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

powraca także 0 w przypadku powodzenia, i jest zadowolony z prostą połączenie, po którym odchodzi.

  • -d oznacza nie czytać niczego od strony klawiatury
  • -v oznacza bycie gadatliwym (to wyłączyć w skrypcie)
  • -z oznacza odłączenie po wykonaniu połączenia
  • - w10 oznacza oczekiwanie do 10 sekund, w przeciwnym razie zrezygnować z:
0

można zintegrować ping do serwera SSH i jeśli to działa dobrze tunel ssh wynosi

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

może to również dobry pomysł, aby umieścić ping w pętli – OkieOth

+0

ping nie pomaga mi dużo, ponieważ generalnie ma ~ 50% pakietów (testowany jest z wyprzedzeniem, i wierzcie lub nie, jest akceptowalny do 50%). – Jarmund

+0

, ale kończy się sukcesem, jeśli tunel jest podniesiony. Jakość jest częścią innych poziomów komunikacji – OkieOth

0

Myślę, że fping może być lepszy niż zwykły ping, bardziej przyjazny dla skryptu.

fping -t 60000 [serwer]

powinien próbować połączyć się z serwerem 60seconds przed rezygnując Coś

if(fping -t 60000 [your server]) { 
execute desired code; 
} else { 
execute this script again to rerun;; 
} 

Chyba masz pomysł, nawet jeśli nie jest kodowanie real.

Powiązane problemy