Piping ping into perl-prog

Discussion in 'Perl' started by bernd wegener, Sep 15, 2004.

  1. Hello netties,

    I coded the following in perl:

    open(LOGFILE,">&STDOUT") ;

    if ( $ARGV[0] ) {

    close(LOGFILE) ;
    open(LOGFILE,">> $ARGV[0]") or die "Cannot open file $ARGV[0]\n" ;
    select(LOGFILE) ; # If commented out, nothing
    $| = 1 ; # is printed to $ARGV[0] later on

    }

    while ( <STDIN> ) {

    ( $sec, $min, $hour, $day, $month, $year ) = localtime() ;
    $month += 1 ;
    $year += 1900 ;

    printf LOGFILE ("%02d.%02d.%04d %02d:%02d:%02d: %s", $day, $month,
    $year,
    $hour, $min, $sec, $_) ;

    }

    The program is intended to receive input line by line from STDIN
    (continuously, e.g. from UNIX-commands like ping or tail -f) and to
    print the input line prepended with a timestamp either to STDOUT or to
    a file if a file name is given on the command line.

    If I pipe an "ordinary" file to this program:

    $ cat test_inp.txt | tstamp.pl

    I get all lines of the file printed to the terminal or to a file:

    $ cat test_inp.txt | tstamp.pl test_out.txt

    each line prepended with the time stamp.

    If I try the same with the select-function and the setting of
    unbuffered output commented out, i.e.,

    close(LOGFILE) ;
    open(LOGFILE,">> $ARGV[0]") or die "Cannot open file $ARGV[0]\n" ;
    # select(LOGFILE) ; # If commented out, nothing
    # $| = 1 ; # is printed to $ARGV[0] later on

    and redirect from a continuously writing program:

    ping <host> | tstamp.pl

    I get proper output on the terminal, but a file as the output target
    remains empty. If instead unbuffered output is used ($| = 1), then
    output to the file works fine as well.

    Does somebody know the reason for this ?

    Any help is appreciated.

    Cheers


    Bernd
    bernd wegener, Sep 15, 2004
    #1
    1. Advertising

  2. bernd wegener

    Joe Smith Guest

    bernd wegener wrote:

    > ping <host> | tstamp.pl
    >
    > I get proper output on the terminal, but a file as the output target
    > remains empty. If instead unbuffered output is used ($| = 1), then
    > output to the file works fine as well.


    You mean "the output target file remains empty until perl's internal
    buffers fill up and perl writes several K bytes all at once".
    Try letting the program run for 24 hours and see what happens.

    > Does somebody know the reason for this ?


    That behavior is exactly what $| was created to control.
    The stdio routines operate differently based on whether the C library
    routine isatty() returns 1 or 0, and perl does so as well.
    Output to non tty file handles gets buffered.
    -Joe
    Joe Smith, Sep 15, 2004
    #2
    1. Advertising

  3. Joe Smith <> wrote in message news:<5W02d.306624$8_6.235832@attbi_s04>...
    > bernd wegener wrote:
    >
    > > ping <host> | tstamp.pl
    > >
    > > I get proper output on the terminal, but a file as the output target
    > > remains empty. If instead unbuffered output is used ($| = 1), then
    > > output to the file works fine as well.

    >
    > You mean "the output target file remains empty until perl's internal
    > buffers fill up and perl writes several K bytes all at once".
    > Try letting the program run for 24 hours and see what happens.
    >
    > > Does somebody know the reason for this ?

    >
    > That behavior is exactly what $| was created to control.
    > The stdio routines operate differently based on whether the C library
    > routine isatty() returns 1 or 0, and perl does so as well.
    > Output to non tty file handles gets buffered.
    > -Joe


    Hi Joe,

    thanks, that was a short but instructive lesson in I/O. If one knows
    it is quite straightforward to understand, but since I was not patient
    enough I did not see "the end", i.e. that eventually the data is
    written to the file. I was not aware of the fact that the
    stdio-library differentiates between terminals and disk files in that
    way.

    I made a little "experiment" on my UNIX-Box, which turned out that the
    first chunk of data written to the file was 8K of size (after a few
    minutes, so it was not necessary to wait 24 h staring at the terminal
    :->>).

    I took the Perl Cookbook, reading a little bit more about buffered /
    non-buffered output ... ;-)

    Thanks and Bye.

    Bernd
    bernd wegener, Sep 16, 2004
    #3
  4. bernd wegener

    Jim Gibson Guest

    In article <>, bernd
    wegener <> wrote:

    > Hello netties,
    >
    > I coded the following in perl:
    >
    > open(LOGFILE,">&STDOUT") ;
    >
    > if ( $ARGV[0] ) {
    >
    > close(LOGFILE) ;
    > open(LOGFILE,">> $ARGV[0]") or die "Cannot open file $ARGV[0]\n" ;
    > select(LOGFILE) ; # If commented out, nothing
    > $| = 1 ; # is printed to $ARGV[0] later on
    >
    > }
    >
    > while ( <STDIN> ) {
    >
    > ( $sec, $min, $hour, $day, $month, $year ) = localtime() ;
    > $month += 1 ;
    > $year += 1900 ;
    >
    > printf LOGFILE ("%02d.%02d.%04d %02d:%02d:%02d: %s", $day, $month,
    > $year,
    > $hour, $min, $sec, $_) ;
    >
    > }
    >
    > The program is intended to receive input line by line from STDIN
    > (continuously, e.g. from UNIX-commands like ping or tail -f) and to
    > print the input line prepended with a timestamp either to STDOUT or to
    > a file if a file name is given on the command line.
    >
    > If I pipe an "ordinary" file to this program:
    >
    > $ cat test_inp.txt | tstamp.pl
    >
    > I get all lines of the file printed to the terminal or to a file:
    >
    > $ cat test_inp.txt | tstamp.pl test_out.txt
    >
    > each line prepended with the time stamp.
    >
    > If I try the same with the select-function and the setting of
    > unbuffered output commented out, i.e.,
    >
    > close(LOGFILE) ;
    > open(LOGFILE,">> $ARGV[0]") or die "Cannot open file $ARGV[0]\n" ;
    > # select(LOGFILE) ; # If commented out, nothing
    > # $| = 1 ; # is printed to $ARGV[0] later on
    >
    > and redirect from a continuously writing program:
    >
    > ping <host> | tstamp.pl
    >
    > I get proper output on the terminal, but a file as the output target
    > remains empty. If instead unbuffered output is used ($| = 1), then
    > output to the file works fine as well.


    What do you mean by "proper output on the terminal". When I run this
    command, I get no output on the terminal, but I do get output to the
    file. Of course, I have to wait awhile because the output is buffered
    and it takes a minute for the ping command to fill up a buffer-full.
    You shouldn't be getting output from the ping command on your terminal
    because you are only writing it to a file.

    >
    > Does somebody know the reason for this ?
    >


    I cannot reproduce your results.

    FYI: this newsgroup is defunct; try comp.lang.perl.misc in the future.
    Jim Gibson, Sep 22, 2004
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Christian Long
    Replies:
    3
    Views:
    10,212
    Duncan Booth
    Jun 26, 2003
  2. runes
    Replies:
    5
    Views:
    494
    runes
    Apr 16, 2005
  3. -intl.com
    Replies:
    1
    Views:
    356
    Martin Gregorie
    Oct 22, 2006
  4. Donn Ingle

    piping into a python script

    Donn Ingle, Jan 24, 2008, in forum: Python
    Replies:
    16
    Views:
    658
    anonymous
    Feb 1, 2008
  5. seth
    Replies:
    8
    Views:
    306
    Tad McClellan
    Jun 11, 2005
Loading...

Share This Page