Perl 中是否有相当于“tail -f”的东西?

发布于 2024-09-18 16:20:13 字数 326 浏览 4 评论 0原文

我正在编写一个脚本,用于侦听日志文件的更改并采取适当的操作。目前我正在使用 open my $fh, "tail -f $logfile |"; 但理想情况下我不想使用系统调用。

我尝试过 File::Tail 但它的最小间隔为 1 秒(我尝试过传递较少的值,但默认为 1 秒,即使我传递了 0 秒)。我检查了它的来源,它似乎正在使用 sleep() ,它需要一个整数。在我尝试自己编写之前,还有其他选择吗?

谢谢。

I'm writing a script that listens for changes to a log file and acts appropriately. At the moment I'm using open my $fh, "tail -f $logfile |"; but ideally I don't want to use system calls.

I've tried File::Tail but it has a minimum interval of 1 second (I've tried passing less but it defaults to 1 second, even if I pass 0). I've checked the source for it and it seems to be using sleep() which takes an integer. Before I try to write my own, are there any other options?

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

软糯酥胸 2024-09-25 16:20:13
  1. 您是否知道 tail -f 默认情况下也使用 1 秒睡眠?这是真的! (至少对于 GNU tail...)
  2. File::Tail 实际上使用 Time::HiRessleep函数,表示休眠时间参数不是整数;您可以将其设置为系统可以处理的任何秒数。
  1. Did you know that tail -f also uses a 1-second sleep by default? It's true! (At least for GNU tail...)
  2. File::Tail actually uses Time::HiRes's sleep function, which means that the sleep time parameter isn't an integer; you can set it to any fractional number of seconds that your system can deal with.
甜心小果奶 2024-09-25 16:20:13

文档中有很多好东西,包括这个问题的答案。来自 perlfaq5 的回答 如何在 perl 中执行“tail -f”?


第一次尝试

seek(GWFILE, 0, 1);

语句eek(GWFILE, 0, 1) 不会改变当前位置,但它确实清除了句柄上的文件结束条件,以便下一个使 Perl 再次尝试读取某些内容。

如果这不起作用(它依赖于你的 stdio 实现的功能),那么你需要更多类似这样的东西:

for (;;) {
  for ($curpos = tell(GWFILE); <GWFILE>; $curpos = tell(GWFILE)) {
    # search for some stuff and put it into files
  }
  # sleep for a while
  seek(GWFILE, $curpos, 0);  # seek to where we had been
}

如果这仍然不起作用,请查看 IO::Handle 中的clearerr方法,该方法会重置错误并结束句柄上的文件状态。

还有来自 CPAN 的 File::Tail 模块。

There's a lot of good stuff in the documentation, including an answer to this exact question. From perlfaq5's answer to How do I do a "tail -f" in perl?


First try

seek(GWFILE, 0, 1);

The statement seek(GWFILE, 0, 1) doesn't change the current position, but it does clear the end-of-file condition on the handle, so that the next makes Perl try again to read something.

If that doesn't work (it relies on features of your stdio implementation), then you need something more like this:

for (;;) {
  for ($curpos = tell(GWFILE); <GWFILE>; $curpos = tell(GWFILE)) {
    # search for some stuff and put it into files
  }
  # sleep for a while
  seek(GWFILE, $curpos, 0);  # seek to where we had been
}

If this still doesn't work, look into the clearerr method from IO::Handle, which resets the error and end-of-file states on the handle.

There's also a File::Tail module from CPAN.

白芷 2024-09-25 16:20:13

在我看来,像您已经做的那样使用 tail -f 管道没有任何问题。在许多情况下,追求语言纯度(例如“无系统调用”)会适得其反。

另外,我在长时间运行的进程中发现了 File::Tail 的问题。不幸的是,我无法用任何确凿的证据来证实这一说法,因为它发生在很久以前,我没有调试问题,而是将 File::Tail 的使用替换为 tail -F代码>管道代替。

In my opinion there is nothing wrong with using tail -f pipe like you already do. In many situations going for language purity like "no system calls" is counterproductive.

Also, I've seen problems with File::Tail in long-running processes. Unfortunately I cannot corroborate this claim with any hard evidence since it happened quite some time ago, I did not debug the problems, replacing the use of File::Tail with a tail -F pipe instead.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文