2012-09-26 14 views
6

Tôi có một kịch bản perl mà khi destilled một chút, trông như thế này:Kiểm tra nếu một đường hầm SSH khởi động và chạy

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 

Cái này là mục tiêu $ ip là vào một liên kết với rất khó lường băng thông, vì vậy đường hầm có thể xuất hiện ngay lập tức, có thể mất một lúc, nó có thể không xuất hiện chút nào. Vì vậy, một giấc ngủ là cần thiết để cung cấp cho đường hầm một thời gian để có được và chạy.

Vì vậy, câu hỏi đặt ra là: Làm thế nào tôi có thể kiểm tra xem đường hầm có đang hoạt động không? 10 giây là một sự chậm trễ thực sự không mong muốn nếu đường hầm đi lên ngay lập tức. Lý tưởng nhất, tôi muốn kiểm tra xem nó có lên và tiếp tục với việc tạo đối tượng telnet một khi nó được, đến tối đa, nói, 30 giây.

Edit: Ping không giúp tôi mouch, như kết thúc từ xa của đường hầm thường là lên, nhưng với một số lượng rất cao của packetloss

quyết: Ngoại suy từ đầu được đề xuất bởi mikebabcock , sleep 10 đã được thay thế bằng khối này hoạt động như một nét duyên dáng:

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

Vì bạn đang sử dụng mô-đun 'Net :: Telnet', bạn đã thử sử dụng lệnh' mở' và thử nghiệm để thành công chưa? Tôi không có chuyên gia Telnet, nhưng đó là điều tôi có thể thử nếu đó là tôi ... –

+0

Tôi có thể làm điều đó nếu không có cách kiểm tra đơn giản: thử lại cho đến khi thành công nếu time_spend_trying <30 giây – Jarmund

Trả lời

6

Sử dụng netcat - thường nc trên các hệ thống Linux:

nc -dvzw10 ${HOSTNAME} 23 

trình đối với tôi, với một phản ứng như:

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

Nó cũng trả về 0 nếu thành công, và hạnh phúc với một đơn giản kết nối sau đó nó biến mất.

  • -d có nghĩa là không đọc bất cứ điều gì từ phía bàn phím
  • -v có nghĩa là tiết (tắt chức năng này trong một kịch bản)
  • -z nghĩa để ngắt kết nối sau khi thực hiện kết nối
  • - w10 có nghĩa là phải chờ tối đa 10 giây, nếu không, hãy từ bỏ
0

bạn có thể tích hợp một ping đến máy chủ ssh của bạn và nếu nó hoạt động tốt đường hầm ssh là lên

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

có lẽ cũng là một ý hay khi đặt ping trong vòng lặp – OkieOth

+0

ping không giúp được gì nhiều, vì nó thường có ~ 50% packetloss (điều này được kiểm tra trước, và tin hay không, nó có thể chấp nhận xuống 50%) – Jarmund

+0

nhưng nó thoát với thành công nếu đường hầm tăng. Chất lượng là một phần của các mức liên lạc khác – OkieOth

0

Tôi nghĩ rằng fping có thể tốt hơn sau đó ping thông thường, nhiều tập lệnh thân thiện hơn.

fping -t 60000 [máy chủ của bạn]

nên cố gắng kết nối với máy chủ 60seconds trước khi từ bỏ Something như

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

Tôi nghĩ rằng bạn sẽ có được ý tưởng ngay cả khi mã hóa không phải là thực.