【问题标题】:PERL: reading Log file and cmd line input togetherPERL:一起读取日志文件和命令行输入
【发布时间】:2011-05-15 05:46:24
【问题描述】:

我编写了一个脚本,它从日志文件中读取一些数据并将数据转换为更简单的形式并将其写回另一个文件。读取是逐行完成的,延迟为 5 秒,即 sleep(5)。

同时,如果用户在命令行上输入“暂停”(通过 STDIN),则程序继续休眠,除非未输入“恢复”,然后读取下一行。

因为,在循环中的每次迭代中,我都会检查 STDIN 是否由用户输入“暂停”。

如果不是,则从文件中读取下一行。但是当我的程序运行时,我必须至少按一个 ENTER 键,否则它不会从输入日志文件中选择下一行,尽管我放了一个 if 语句来检查 STDIN 是否未定义。

我不是 perl 专家,这是我第一次用 PERL 编写代码。事实上我以前从来没有做过这个文件解析的事情:'-(

我的代码实现是这样的;

#!/usr/local/bin/perl
my $line_no = 0;my $cancel = 0; my $line = "";
my $curpos = 0; my $whence = 0;

my $log_file = "/var/log/tmp_nagios.log";
#open(LOGFILE, "+< $log_file")or die "Failed to open $log_file, $!";

my $inp_file = "/var/log/sec_input";
my $logbuffer="";

#open(LOGFILE, "+< $log_file")or die "Failed to open $log_file, $!";
my $in;

while(1){
    print "in While (1) Pos: $curpos and Whence:$whence\n";

    open(LOGFILE, "+< $log_file")or die "Failed to open $log_file, $!";
    seek(LOGFILE, $curpos, $whence);
    next if(eof(LOGFILE));

    print "Beginning\n";
    while(<LOGFILE>){
            #chomp($in = <STDIN>);
            #if(defined($in) && $in =~ /^suspend$/i){
            ### Problem here ###
            if(defined(<STDIN>) && <STDIN> =~ /^suspend\n$/i){ ## checking if 'suspend' is entered
                    print "Suspend Mode";
                    do{
                            sleep(5);
                    }while(!(<STDIN> =~ /^resume\n$/i));
                    print "Resume now\n";
                    close(LOGFILE);
                    last;
            }
            else{
                    $line = $_;
                    if($line =~ m/^\[(\d+)\]\sCURRENT\sSERVICE\sSTATE:\s(\w+);(\w+|\_|\d+)+;(CRITICAL|OK);.+$/){
                            $logbuffer = "$1,$2-$3,$4\n";
                            print $logbuffer;
                            open(INPFILE, ">> $inp_file")or die "Failed! to open $inp_file, $!";
                            #print INPFILE $logbuffer;
                            close(INPUTFILE);
                            sleep(5);
                            $curpos = tell(LOGFILE);
                            $whence = 1;
                    }
            }
    }
    print "\nRe openning the file from Pos=$curpos and Whence=$whence\n";
   }
   close(LOGFILE);

这里是示例日志文件 (/var/log/tmp_nagios.log) 数据;

[1284336000] 当前服务状态:host1;event1;CRITICAL; s

[1284336000] 当前服务状态:host2;event1;CRITICAL; f

[1284336000] 当前服务状态:host3;event3;CRITICAL; g

[1284336000] 当前服务状态:host4;event4;CRITICAL; j

[1284336000] 当前服务状态:host5;event1;CRITICAL; s

[1284336000] 当前服务状态:host6;event1;CRITICAL; f

[1284336000] 当前服务状态:host7;event7;CRITICAL; s


对不起各位!错别字

一开始我说过,'我的脚本正在从日志文件中读取数据,延迟 5 秒,即 sleep(5)'

但实际上我忘记在我的代码中提及它,因此,取消注释这一行:#sleep(3);并让 'sleep(5);'

谢谢

【问题讨论】:

  • 如果您的帖子中有问题会更好。我确实在代码中看到了有关挂起检查的注释。不过,代码有点杂乱无章的注释部分。现在,我建议您将代码简化为解析日志文件的循环,使其工作,然后然后添加暂停/恢复的信号检查。

标签: perl stdin


【解决方案1】:

如果我正确理解了您的问题:请查看Term::ReadKey CPAN 模块。

您可以使用它来进行非阻塞缓冲区读取。 (如果缓冲区中没有任何内容,您的脚本不会暂停用户输入)

https://metacpan.org/pod/Term::ReadKey

您可能还想稍微不同地处理这个问题 - 使用信号: http://perldoc.perl.org/perlipc.html。您可以让程序正常运行,但捕获中断(例如CTRL-C

或者,您可以只使用CTRL-Zfg 让您的脚本休眠和唤醒。

【讨论】:

    【解决方案2】:

    另一个选项是POE::Wheel::FollowTail 用于日志,POE::Wheel::ReadLineTerm::Visual 用于用户输入。虽然这可能有点矫枉过正

    【讨论】:

      猜你喜欢
      • 2013-12-26
      • 1970-01-01
      • 1970-01-01
      • 2011-12-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-21
      相关资源
      最近更新 更多