我正在寫一個腳本來解析Java中的線程轉儲。由於某些原因,當我嘗試從子例程內或在嵌套循環內讀取時,它根本不會進入嵌套循環。理想情況下,我希望能夠在嵌套循環上對STDIN進行操作,否則您將不得不編寫一些醜陋的狀態轉換代碼。如何在perl中執行<STDIN>的嵌套讀取?
在我使用STDIN之前,爲了確保我的子程序沒有指向STDIN的獨立指針,我將它打開爲$in
。
當我運行它時,它看起來像下面。儘管外層循環有更多來自STDIN的文件可以讀取,但您可以看到它永遠不會進入嵌套循環。
~/$ cat catalina.out-20160* | thread.dump.find.all.pl
in is GLOB(0x7f8d440054e8)
found start of thread dump at 2016-06-17 13:38:23 saving to tdump.2016.06.17.13.38.23.txt
in is GLOB(0x7f8d440054e8)
BEFORE NESTED STDIN
BUG!!!!
found start of thread dump at 2016-06-17 13:43:05 saving to tdump.2016.06.17.13.43.05.txt
in is GLOB(0x7f8d440054e8)
BEFORE NESTED STDIN
BUG!!!!
...
代碼:
#!/usr/bin/perl
use strict;
use warnings;
use Getopt::Long;
use DateTime::Format::Strptime;
use DateTime::Format::Duration;
use Data::Dumper;
# DO NOT touch ARGV!
Getopt::Long::Configure("pass_through");
# cat catalina.out-* | thread.dump.find.all.pl
sub processThreadDump {
my $in=$_[0];
my $currentLine=$_[1];
my $prevLine=$_[2];
my $parsedDatetime=$_[2];
# 2016-09-28 09:27:34
$parsedDatetime=~ s/[ \-\:]/./g;
my $outfile="tdump.$parsedDatetime.txt";
print " saving to $outfile\n";
print " in is $in\n";
open(my $out, '>', $outfile);
print $out "$prevLine\n";
print $out "$currentLine\n";
print "BEFORE NESTED STDIN\n";
foreach my $line (<$in>) {
print "INSIDE NESTED STDIN\n";
$line =~ s/\R//g; #remove newlines
print $out "$line\n";
if($line =~ m/JNI global references:/) {
print "PROPERLY LEFT NESTED STDIN\n";
close($out);
return;
} elsif($line =~ m/Found \d+ deadlock\./) {
print "PROPERLY LEFT NESTED STDIN\n";
close($out);
return;
}
}
print "BUG!!!!\n";
close($out);
}
open(my $in, '<-');
print "in is $in\n";
my $prevLine;
# read from standard in
foreach my $line (<$in>) {
$line =~ s/\R//g; #remove newlines
if($line =~ m/Full thread dump OpenJDK 64-Bit Server VM/) {
# we found the start of a thread dump
print "found start of thread dump at ${prevLine}";
processThreadDump($in, $line, $prevLine);
} else {
#print "setting prev line to $line\n";
$prevLine=$line;
}
}
close($in);
最好在一個地方讀取任何流。不要嵌套它們。相反,請爲輸入設置一個狀態機。然後可以根據狀態將每行輸入分派到適當的處理。 – shawnhcorey
@shawnhcorey:是的,工作。但是,我發現功能比狀態機更容易推理。 – joseph
時間來升級你的技能。 – shawnhcorey