Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine

tail pipe

by aquercus (Initiate)
on Jun 19, 2013 at 21:42 UTC ( #1039848=perlquestion: print w/replies, xml ) Need Help??
aquercus has asked for the wisdom of the Perl Monks concerning the following question:

The testing reports for the approaches listed here ( do not report success in windows applications.

The environment is ActiveState perl on a windows 7 box. I want to read records into my perl program from a file as they are being written to it by an external program. While windows does not have an internal tail command, MS does provide one as described at this site: ( Upon execution, this works fine except the output from tail goes to a command window and is not capture-able in perl by any means I can develop. I'm seeking an equivalent capability using perl's file IO functions. Thanks;

#! /usr/bin/perl my $cmdtorun = "tail -f D:/prjct/logger/2013-06-05.dlg |"; open(TL, $cmdtorun) || die "Failed: $!\n"; while ( <TL> ) { print "Got: $_\n"; }

Replies are listed 'Best First'.
Re: tail pipe
by kcott (Chancellor) on Jun 20, 2013 at 07:02 UTC

    G'day aquercus,

    Welcome to the monastery.

    I don't have perl running on any MSWin OSes; however, here's how I might have tackled this on a *nix OS. There may be sufficient here for you to adapt it to your OS. I've added some notes after the code as well as a sample run.

    Here's the code (

    #!/usr/bin/env perl use strict; use warnings; use autodie qw{:all}; my $tail_cmd = 'tail -f ./pm_test_file_to_tail'; my @tail_captures; print '*** Start reading from $tail_pipe at ', time, "\n"; my $tail_pid = open my $tail_pipe, '-|', $tail_cmd; { local $SIG{INT} = sub { kill INT => $tail_pid if kill 0 => $tail_pid; waitpid $tail_pid => 0; }; while (<$tail_pipe>) { push @tail_captures, $_; } } print '*** Stop reading from $tail_pipe at ', time, "\n"; # Possibly process data captured, e.g. for demo only $_ = uc for @tail_captures; print '*** Captured via $tail_pipe:', "\n"; print for @tail_captures;


    • I haven't included the pipe (|) as part of the tail command. Instead, I've used '-|' in the 3-argument form of open and captured the PID of the tail process.
    • local $SIG{INT} = ... traps interrupts (Ctrl-C on *nix) to stop tailing without killing the script. This only takes effect within the anonymous block so it only affects the while loop; outside of this block, interrupts act normally, i.e. Ctrl-C will terminate the script.
    • perlport may be of use with respect to kill and waitpid.
    • perlipc has information on Signals.

    Sample run:

    File to TailTailing Process

    Assume some log file that already has some data

    $ cat > pm_test_file_to_tail line 1 line 2 line 3

    [terminated with Ctrl-D]


    External program starts appending data

    $ cat >> pm_test_file_to_tail line 4 line 5

    Start tailing the file

    $ *** Start reading from $tail_pipe at 1371707519

    External program appends more data

    line 6 line 7

    [terminate tailing with Ctrl-C]

    ^C*** Stop reading from $tail_pipe at 1371707542 *** Captured via $tail_pipe: LINE 1 LINE 2 LINE 3 LINE 4 LINE 5 LINE 6 LINE 7

    External program still appending data

    line 8 line 9

    [External program terminated with Ctrl-D]


    Check final contents of tailed file

    $ cat pm_test_file_to_tail line 1 line 2 line 3 line 4 line 5 line 6 line 7 line 8 line 9

    -- Ken

      Thanks very much for this detailed response but unfortunately the problem remains the same: Since the "tail" available on windows is the MS toolkit program, the output from it continues to be displayed in a command window it creates, and is not captured in your perl program.

Re: tail pipe
by davido (Archbishop) on Jun 19, 2013 at 22:28 UTC
    <c> #! /usr/bin/perl my $cmdtorun = "tail -f D:/prjct/logger/2013-06-05.dlg |"; open(TL, $cmdtorun) || die "Failed: $!\n"; while ( <TL> ) { print "Got: $_\n"; } <c/>

    Can you place your question and your code in the same post? A question without code is often difficult to decipher. Code without a question is impossible to answer. A winning combination usually includes both.


Re: tail pipe
by NetWallah (Canon) on Jun 20, 2013 at 03:48 UTC
    Try File::Tail .

                 "The trouble with the Internet is that it's replacing masturbation as a leisure activity."
            -- Patrick Murray

Re: tail pipe
by BrowserUk (Pope) on Jun 20, 2013 at 17:55 UTC

    This works for me:

    #! perl -slw use strict; my $tail = "c:\\Program Files (x86)\\Windows Resource Kits\\Tools\\tai +l.exe"; ## Create an asynchronous process writing a file to tail system 1, q[ perl -E"$|++; sleep(1),say for 1 .. 1000" > log ];; ## Note: the quoting. my $pid = open PIPE, '-|', qq[ "$tail" /f log ] or die $!;; ## Print the output till the pipe runs dry print while <PIPE>;; __END__ C:\test>junk29 2 3 4 5 6 7 8 9 10 11 12 13 14 Terminating on signal SIGINT(2) Terminating on signal SIGINT(2) C:\test>TAIL: write() failed C:\test>

    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
Re: tail pipe
by Laurent_R (Canon) on Jun 19, 2013 at 21:57 UTC

    Please show your code, it might be easier to understabnd exactly what you are doing and to help you out.

      Here is the program. It assumes that that the MS tookit tail has been installed on the computer.

      #! /usr/bin/perl my $cmdtorun = "tail -f D:/prjct/logger/2013-06-05.dlg |"; open(TL, $cmdtorun) || die "Failed: $!\n"; while ( <TL> ) { print "Got: $_\n"; }

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1039848]
Approved by Happy-the-monk
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others about the Monastery: (3)
As of 2018-01-21 22:36 GMT
Find Nodes?
    Voting Booth?
    How did you see in the new year?

    Results (230 votes). Check out past polls.