Re: OT: tail -f | while read
On Thu, 6 Sep 2001, Martin F Krafft wrote:
> hi,
> why does the following not work:
>
> tail -f /var/log/syslog | grep something | while read i; do myprog $i; done
>
> i basically need to run myprog as soon as a new entry in syslog
> happens that matches the criteria of the grep call. it needs to happen
> immediately.
Here is a far more complicated perl script that make the "tail -f" part of the
actual application. It is designed to run as a daemon ie
# logtail /var/log/syslog &
----
#!/usr/bin/perl -w
use strict;
use Fcntl;
sub sig_quit();
sub sig_usr1();
sub processLines($);
sub errorMSG($);
sub processLine($);
my $logName = shift;
my $maxReadSize = 4096;
my $numReads = 0;
my $data;
my %data;
my $eof;
my $currpos;
$SIG{INT} = 'sig_quit';
$SIG{QUIT} = 'sig_quit';
$SIG{USR1} = 'sig_usr1';
sysopen(logFD,$logName,O_RDONLY);
seek(logFD, 0, 0);
$data = processLines('');
print "Done BackData\n";
$currpos=($eof=sysseek(logFD,0, 1));
while (1) {
$eof=sysseek(logFD,0, 2);
if ($currpos > $eof) {
errorMSG("==> file truncated <==\n");
$data='';
$currpos=$eof;
} elsif ($currpos != $eof) {
sysseek(logFD,$currpos,0);
$data = processLines($data);
$currpos=($eof=sysseek(logFD,0, 1));
} else {
sleep 1;
}
}
close(logFD);
sub sig_quit() {
errorMSG("bye bye. ($numReads)\n");
close(logFD);
exit;
}
sub sig_usr1() {
errorMSG("I caught a signal I _should_really do something\n");
}
sub processLines($) {
my $data = shift;
my $buff;
my $bytesRead;
while (($bytesRead = sysread(logFD,$buff,$maxReadSize))!=0) {
$numReads++;
$data.=$buff;
while ($data =~ s/\A(.*?\n)//m) {
processLine($1);
}
}
return $data;
}
sub processLine($) {
$_=shift;
chmop;
#Do SOMETHING HERE
}
sub errorMSG($) {
my $buff=shift;
syswrite(STDERR,$buff,length($buff));
}
__END__
----
I know this is way beyond the scope of your question but it may help.
Yours Tony.
/*
* "The significant problems we face cannot be solved at the
* same level of thinking we were at when we created them."
* --Albert Einstein
*/
Reply to: