我正在使用 Perl 读取可能在任何时候被截断的日志文件。如果发生这种情况,我想再次从头开始读取文件,但默认的 Perl 行为似乎是等到文件指针赶上。例如,如果我运行以下命令:
perl -e 'open FILE, "test"; while (1) { $line = <FILE>; print "$line"; }'
然后做:
for i in 1 2 3; do echo $i >> test; done
:>test
for i in 4 5 6 7; do echo $i >> test; done
我得到的输出是:
1
2
3
7
但如果我要做同样的事情,将 Perl 代码替换为:
tail -f test
然后(忽略到stderr的尾部输出)我得到我想要的输出,即:
1
2
3
4
5
6
7
显然,我不能只使用tail,因为我想对线路本身进行一些处理。我确实有一个想法是将两者结合起来:
tail -f test | perl -e 'while (1) { $line = <STDIN>; print "$line"; }'
它适用于我的 Linux 开发机器,但不幸的是不适用于 Solaris 目标平台。
有任何想法吗?
根据要求,使用 File::Tail 的示例如下:
perl -e 'use File::Tail; $file = File::Tail->new("test"); while (defined($line=$file->read)) { print "$line"; }'
如果我像以前一样将数据输入到测试中,我得到的输出只是:
7
这显然不是所希望的。我尝试调整 File::Tail 将等待的 maxinterval,如下所示:
perl -e 'use File::Tail; $file = File::Tail->new(name => "test", maxinterval => 1); while (defined($line=$file->read)) { print "$line"; }'
但在这种情况下,将数据输入测试文件太快了,如下所示:
for i in 1 2 3; do echo $i >> test; done; :>test; for i in 4 5 6 7; do echo $i >> test; done
结果只是:
4
5
6
7
不幸的是,对于我们(非常繁忙的)应用程序来说,这是一个现实的场景。为了比较起见,Linux tail 似乎可以正确处理那种数据输入速度,所以很明显可以做到(尽管公平地说,也许不是在 Perl 中......?)