2017-03-13 12 views
0

TNSPingユーティリティを使用してホスト名とポート番号を取得する必要があるTNS名がたくさんあります。条件に基づいてperlでコマンドを終了します

while (my $line = <$fh>) { 
    chomp $line; 
    print "TNS: $line\n"; 
    my $output = `tnsping $line | grep -Eo "HOST=[A-Za-z0-9.\-]*com?|PORT=[0-9]+"`; 
    print "$output\n"; 
    print "----------------\n\n"; 
} 

tnspingの出力は、コードはTNSエントリのほとんどのために正常に動作しますが、特定のエントリのために、tnspingコマンドが出ないあるこの

TNS Ping Utility for Linux: Version 11.1.0.0.2 on 15-FEB-2009 14:46:28 

Copyright (c) 1997, 2009 Oracle Corporation. All rights reserved. 

Used parameter files: 
Used TNSNAMES adapter to resolve the alias 
Attempting to contact (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = 
TCP)(HOST = sampleserver.com)(PORT = 1521))) (CONNECT_DATA = (SERVICE_NAME = 
sales.us.example.com))) 
OK (10 msec) 

ようになりますであり、したがって打たれる。私はこれらのエントリの1つを手動で実行しようとしましたが、stdoutに印刷していることがわかりましたが、何らかの理由でtnspingユーティリティが終了していません。

私の質問は、tnspingユーティリティが終了するかどうかにかかわらず、ホストとポートのデータを取得すると次のエントリに移動するようにスクリプトを変更する方法は?

私の現在の理解は、tnspingユーティリティが終了した場合にのみ、grepが動作する(私は連続していません)。

私は他の方法にもオープンしています。

+0

あなたのコマンド 'timeout 20s your command'にタイムアウトを追加することができます。また、 'command&sleep 10;を使うこともできます。 $! 'を殺す。コマンドが10秒で完了しないと、それは殺されます。 。 – Ayush

答えて

4

IO::Selectcan_readを使用することをおすすめします。私もお勧めします - grep perl内で実行しないでください。このような

何か:

while (my $line = <$fh>) { 
    chomp $line; 
    print "TNS: $line\n"; 

    my $pid = open(my $output, '-|', 'tnsping $line'); 
    my $select = IO::Select->new($output); 

    my $host; 
    my $port; 
    #check if the FH is readable, with a 5s timeout. 
    while ($select->can_read(5)) { 
     my $line = <$output>; 
     $line =~ m/HOST\s*=\s*([A-Za-z0-9.\-]*com?)/ and $host = $1; 
     $line =~ m/PORT\s*=\s*([0-9]+)/ and $port = $1; 
    } 
    close($output); 
    print $host, "\n"; 
    print $port, "\n"; 
    print "$output\n"; 
    print "----------------\n\n"; 
} 

私はスタイルのポイントとしてお勧めしたい - $fhは偉大な変数名ではありません。

関連する問題