gpt4 book ai didi

perl - 读取在 Perl 中可能被截断的文件

转载 作者:行者123 更新时间:2023-12-02 00:10:34 26 4
gpt4 key购买 nike

我正在使用 Perl 读取可能随时被截断的日志文件。如果发生这种情况,我想再次从头开始读取文件,但默认的 Perl 行为似乎是等到文件指针 catch 。例如,如果我运行以下命令:

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 将等待的最大间隔,如下所示:

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 中不行......?)

最佳答案

Linux tail command使用 inotify机制来监视对文件的更改,而不必重复轮询它以获取更新。这使其能够快速可靠地响应文件中的任何更改。

要在 Perl 中实现类似的功能,您可以使用 Linux::Inotify2来自 CPAN 的模块。不幸的是,正如名称所示,此模块仅适用于 Linux,因此它无法帮助您将脚本移植到 Solaris。

可能能够使用FAMSGI::FAM模块代替;如果没有可用的 native 文件更改通知机制,它可能仍会在内部回退到轮询,但至少它应该提供一个相当不错且经过测试的文件轮询实现。

关于perl - 读取在 Perl 中可能被截断的文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15659121/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com