I got tired of tailing an error log and hitting enter several times to create a gap between requests, so I automated this behaviour. This script will tail a file and print a line '='x80 whenever there is a 2 second silent period - but will not output multiple separator lines for long silent periods.
#!/usr/bin/perl use strict; use warnings; # Pipe the output of tail -f open TAIL, "tail -f @ARGV |" or die "Failed to pipe to 'tail -f @ARGV' +. $!"; # Create a handle for SIGALRM that outputs a line of '=', 80 width. $SIG{ALRM}=sub{ printf "\n%s\n", '='x80; }; # Read from TAIL # Print output # Set the alarm timer to 2 seconds. # # By setting the alarm to 2 seconds with each line processed we can de +tect # the first 2 second silent period, and trigger $SIG{ALRM}. # After the alarm is triggered no further separators will be output un +til the # # This will not trigger multiple separator lines, since alarm will not + be reset # to 2 seconds until the next line is read. # print && alarm(2) while<TAIL> __END__ =head1 NAME tf - script for tailing a file and outputting a separator line when in +active =head1 SYNOPSIS tf /var/log/messages =cut

Replies are listed 'Best First'.
Re: tf - tail a file and output separator line when inactive
by Hue-Bond (Priest) on Jul 18, 2006 at 17:06 UTC

    Often I find myself doing tail -f file | grep --line-buffered "kernel" and your program has given me the inspiration to automate that. This is my version. It features taint mode and File::Tail:

    #!/usr/bin/perl -T use strict; use warnings; use File::Tail; die "Not enough arguments\n" unless @ARGV; my ($file, $regex) = @ARGV; $regex = '.' unless defined $regex && length $regex; my $tail = File::Tail->new ( name => $file, maxinterval => 5, adjustafter => 10, ); $SIG{ALRM} = sub { printf "\n%s\n", '='x80; }; while (defined ($_ = $tail->read)) { print && alarm 2 if /$regex/; }

    Let me anticipate that someone is going to reply talking about code interpolation in the regex:

    # ~/bin/tf2.pl file '(??{print "Hello, world!\n"})' Eval-group not allowed at runtime, use re 'eval' in regex m/(??{print +"Hello, world!\n"})/ at /root/bin/tf2.pl line 20.

    Update: Minor change according to imp's comment.

    --
    David Serrano

      Nice addition.

      I would only change one thing:

      while (defined ($_ = $tail->read)) { if (/$regex/) { print; alarm 2; } }

      That will prevent separator lines after reading a line that was filtered.

      use re 'eval'; would remove the error, but using it would defy taint checking.

        My point is precisely that there's no way of running arbitrary code even when the regex isn't being checked or cleaned. Of course, the user running this will often be root so this is only an issue if the script is somehow made setuid. I only pointed it out to avoid the typical subthread about "Your usage of /$regex/ is insecure!".

        --
        David Serrano

        using it would defy taint checking.

        You mean “defeat” – unless you want to say that the code will doggedly refuse to be taint-checked. :-)

        Makeshifts last the longest.