Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   Perl (http://www.velocityreviews.com/forums/f17-perl.html)
-   -   Piping ping into perl-prog (http://www.velocityreviews.com/forums/t25368-piping-ping-into-perl-prog.html)

bernd wegener 09-15-2004 09:31 AM

Piping ping into perl-prog
 
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

Joe Smith 09-15-2004 07:41 PM

Re: Piping ping into perl-prog
 
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

bernd wegener 09-16-2004 04:47 PM

Re: Piping ping into perl-prog
 
Joe Smith <Joe.Smith@inwap.com> 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

Jim Gibson 09-22-2004 06:32 PM

Re: Piping ping into perl-prog
 
In article <18b5338b.0409150131.29cf7605@posting.google.com >, bernd
wegener <bew_ba@gmx.net> 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.


All times are GMT. The time now is 10:28 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.