我编写了一个脚本,它从日志文件中读取一些数据,并将数据转换为更简单的形式并将其写回另一个文件。读数是逐行完成的,延迟5秒,即睡眠(5)。
同时,在命令行中,如果用户输入'suspend'(通过STDIN),程序将继续进入睡眠状态,除非未输入'resume',然后读取下一行。
因为,在循环中的每次迭代中,我都在检查STDIN是否由用户输入“suspend”。
如果没有,则从文件中读取下一行。但是当我的程序运行时,我必须至少按一个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;小号
[1284336000]当前服务状态:host2; event1; CRITICAL; ˚F
[1284336000]当前服务状态:host3; event3; CRITICAL;克
[1284336000]当前服务状态:host4; event4; CRITICAL; Ĵ
[1284336000]当前服务状态:host5; event1; CRITICAL;小号
[1284336000]当前服务状态:host6; event1; CRITICAL; ˚F
[1284336000]当前服务状态:host7; event7; CRITICAL;小号
对不起伙计们!错字错误
一开始我说,'我的脚本正在从日志文件读取数据,延迟5秒,即睡眠(5)'
但实际上我忘记在我的代码中提及它,因此,取消注释这一行:#sleep(3);并使'睡觉(5);'
感谢
答案 0 :(得分:1)
如果我已正确理解您的问题:请查看Term::ReadKey
CPAN模块。
您可以使用它来执行非阻塞缓冲区读取。 (如果缓冲区中没有任何内容,则脚本不会暂停以供用户输入)
https://metacpan.org/pod/Term::ReadKey
您可能也希望以稍微不同的方式处理此问题 - 使用信号:
http://perldoc.perl.org/perlipc.html。您可以让程序正常运行,但捕获中断(例如CTRL-C
)
或者,您可以使用CTRL-Z
和fg
让您的脚本保持睡眠和唤醒状态。
答案 1 :(得分:0)
另一个选项是POE::Wheel::FollowTail用于日志,POE::Wheel::ReadLine或Term::Visual用于用户输入。虽然这可能有点矫枉过正