根据条件在perl中终止命令

时间:2017-03-13 10:11:56

标签: perl shell

我有很多TNS名称,我必须使用TNSPing实用程序从中获取主机名和端口号。

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 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)

该代码适用于大多数TNS条目,但对于某些条目,tnsping命令未退出,因此受到攻击。我尝试手动运行其中一个条目,我发现它们正在打印到stdout但由于某种原因,tnsping实用程序没有退出。

现在我的问题是,无论tnsping实用程序是否退出,我如何修改脚本以便在获取主机和端口数据后移动到下一个条目?

我目前的理解是,只有当tnsping实用程序退出时,grep才会起作用(我,它不是连续的)。

我也对任何其他方法持开放态度。

1 个答案:

答案 0 :(得分:4)

我建议使用IO::Selectcan_read。我还建议 - 不要在perl中运行grep

这样的事情:

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不是一个很好的变量名。