gpt4 book ai didi

linux - 如何在 Perl 中处理来自连续流程管道的更新

转载 作者:IT王子 更新时间:2023-10-29 01:25:59 26 4
gpt4 key购买 nike

我试图在 Fedora 上跟踪 Perl 中的日志文件,但不幸的是,Fedora 使用 journalctl 读取我无法直接解析的二进制日志文件。根据我的理解,这意味着我只能通过调用 journalctl 来读取 Fedora 的日志文件。

我尝试使用 IO::Pipe这样做,但问题是 $p->reader(..) 一直等到 journalctl --follow 完成写入输出(自从 --follow 就像 tail -F) 然后允许我打印出所有不是我想要的东西。我希望能够设置一个回调函数,以便在每次将新行打印到流程管道时调用,以便我可以解析/处理每个新的日志事件。

use IO::Pipe;

my $p = IO::Pipe->new();
$p->reader("journalctl --follow"); #Waits for process to exit

while (<$p>) {
print;
}

最佳答案

我假设 journalctltail -f 一样工作.如果这是正确的,一个简单的 open应该做的工作:

use Fcntl; # Import SEEK_CUR

my $pid = open my $fh, '|-', 'journalctl --follow'
or die "Error $! starting journalctl";
while (kill 0, $pid) {
while (<$fh>) {
print $_; # Print log line
}
sleep 1; # Wait some time for new lines to appear
seek($fh,0,SEEK_CUR); # Reset EOF
}

open打开一个文件句柄以读取被调用命令的输出:http://perldoc.perl.org/functions/open.html

seek用于重置 EOF 标记:http://perldoc.perl.org/functions/seek.html无需重置,所有后续 <$fh>即使被调用的脚本同时发出额外的输出,调用也只会返回 EOF。

kill 0,$pid只要子进程由 open 启动,就会为真还活着。

您可以替换 sleep 1通过 usleep来自 Time::HiRes select undef,undef,undef,$fractional_seconds;根据传入线路的频率等待不到一秒钟。

AnyEvent也应该能够通过它的 AnyEvent::Handle 完成这项工作.

更新:

添加use POSIX ":sys_wait_h";在开头和waitpid $pid, WNOHANG)到外循环也会检测(并收获)一个僵尸 journalctl过程:

while (kill(0, $pid) and waitpid($pid, WNOHANG) != $pid) {

一个守护进程可能还想检查是否 $pid仍然是当前进程 ( $$ ) 的子进程,如果它仍然是原始进程 journalctl过程。

关于linux - 如何在 Perl 中处理来自连续流程管道的更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36959178/

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