system-admin intermediate

How to tail -f a log file in Perl script?

Question

How to tail -f a log file in Perl script?

Tailing a Log File Like tail -f in Perl

The Unix command tail -f continuously monitors the end of a growing file, such as a log file. In Perl, you can replicate this behavior by reading from a filehandle, seeking to the file's end initially, and then waiting for new lines to be appended. This allows real-time monitoring directly within your Perl script without relying on external utilities.

Key Concepts

  • Filehandle and seek: Open the file and move to the end so only new lines are read as they appear.
  • EOF handling: When no new line is available, pause briefly, reset the EOF indicator using seek, and retry.
  • Autoflush: Set $| = 1 to force immediate STDOUT output rather than buffered.

Perl Specific Notes

  • Perl uses sigils like $ for scalars and <> angle brackets to read lines from a filehandle.
  • seek($fh, 0, 1) is a classic Perl trick to clear EOF on a filehandle, enabling rereading as the file grows.
  • Perl's $/, the input record separator, defaults to newline, so line-based reads work as expected.

Common Gotchas

  • Make sure the file you tail exists and is readable to avoid errors.
  • Infinite loops without a termination condition can hang your script—consider signal handling for real-world use.
  • Log rotation requires extra logic, as the filehandle does not auto-update on file replacement.

Example: Demonstrating tail -f Pattern in Perl

This example demonstrates the core pattern for tailing a file. Since sandbox environments don't allow file I/O or infinite loops, this version simulates the technique by showing how new content would be detected and printed, with a bounded loop for demonstration purposes.


use strict;
use warnings;

# Simulate a log file as an in-memory array
my @log_lines = (
    "Initial line 1\n",
    "Initial line 2\n"
);

# Simulate file position (starting at end)
my $position = scalar @log_lines;

# Autoflush STDOUT
$| = 1;

print "Simulating tail -f behavior:\n";
print "Starting position: $position lines\n\n";

# Simulate new lines being appended to the log
push @log_lines, "New log entry at " . localtime() . "\n";
push @log_lines, "Another new entry\n";
push @log_lines, "Final entry for demo\n";

# Tail loop - check for new lines (limited iterations for sandbox)
for my $check (1..5) {
    while ($position < scalar @log_lines) {
        print $log_lines[$position];
        $position++;
    }
    
    if ($position >= scalar @log_lines) {
        print "[Check $check: No new lines, would sleep and retry...]\n";
    }
    
    last if $check == 3;  # Exit after demonstrating the pattern
}

print "\nIn a real tail -f, this would loop indefinitely.\n";

Explanation

This script demonstrates the tail -f pattern without filesystem access:

  • Uses an array to simulate log file contents that can grow over time.
  • Tracks a position pointer, analogous to a file pointer after seeking to EOF.
  • Checks for new entries beyond the current position and prints them.
  • Shows the sleep-and-retry pattern when no new content is available.
  • Uses bounded iteration to avoid timeout in sandbox environments.

Real Implementation Pattern

In production with actual files, you would use open, seek($fh, 0, 2) to jump to EOF, and seek($fh, 0, 1) to clear EOF status between read attempts. The core logic remains the same: continuously check for new content, print it immediately, and wait briefly when the end is reached.

Verified Code

Executed in a sandbox to capture real output. • v5.34.1 • 8ms

Tip: edit code and use “Run (Browser)”. Server runs always execute the published, verified snippet.
STDOUT
Simulating tail -f behavior:
Starting position: 2 lines

New log entry at Tue Dec 30 13:25:54 2025
Another new entry
Final entry for demo
[Check 1: No new lines, would sleep and retry...]
[Check 2: No new lines, would sleep and retry...]
[Check 3: No new lines, would sleep and retry...]

In a real tail -f, this would loop indefinitely.
STDERR
(empty)

Was this helpful?

Related Questions