> From: Andrew Gaffney [mailto:[EMAIL PROTECTED] 
> Sent: Monday, 23 February 2004 12:35 AM
> To: David le Blanc
> Cc: [EMAIL PROTECTED]
> Subject: Re: parsing Makefiles
> 
> David le Blanc wrote:
> >>From: Andrew Gaffney [mailto:[EMAIL PROTECTED] 
> >>Sent: Sunday, 22 February 2004 6:09 PM
> >>To: David le Blanc
> >>Cc: [EMAIL PROTECTED]
> >>Subject: Re: parsing Makefiles
> >>
> >>David le Blanc wrote:
> >>
> >>>>I've come up with some *simple* code that seems to work:
> >>>>
> >>>>#!/usr/bin/perl
> >>>>
> >>>>use strict;
> >>>>use warnings;
> >>>>
> >>>>$| = 1;
> >>>>my $total = `make -n | wc -l`;
> >>>>my ($count, $line);
> >>>>open MAKE, "make |";
> >>>>foreach $line (<MAKE>) {
> >>>>  $count++;
> >>>>  my $percent = int(($count / $total) * 100);
> >>>>  print "..$percent";
> >>>>}
> >>>
> >>>
> >>>You may find that the 'MAKE' file handle is buffered by the make
> >>>application.
> >>>
> >>>I order to ensure 'make' doesn't buffer its output, you 
> >>
> >>need to run it
> >>
> >>>in its
> >>>own pseudo-terminal.   The Expect module may be able to 
> >>
> >>help, since it
> >>
> >>>runs
> >>>apps in pseudo-terminals, or someone else may offer a 
> >>
> >>better solution.
> >>
> >>Its not the 'make' output that's being buffered. That doesn't 
> >>get printed at all. Its my 
> >>output that does appear until the whole run is done.
> > 
> > Ok,  Lets break down what is really going on here.
> > 
> > 
> > Your  loop construct:
> > 
> > foreach $line (<MAKE>) {
> >     .. print stuff ..
> > 
> > }
> > 
> > is looping BASED ON THE OUTPUT of the make command.  
> > 
> > Since the MAKE COMMAND OUTPUT is being buffered by the make command,
> > you will find that NOTHING arrives in the 'foreach' loop until the
> > entire 
> > make has complete and FLUSHED its output.
> > 
> > Hence, if you want to print output as the MAKE COMMAND 
> OUTPUT arrives,
> > you
> > must make sure the COMMAND OUTPUT arrives in a timely manner.. I.e.
> > unbuffered.
> 
> I understand. I modified my code to verify this:
> 
> #!/usr/bin/perl
> 
> use strict;
> use warnings;
> 
> #$| = 1;
> my $total = `make -n | wc -l`;
> print "$total\n";
> my ($count, $line);
> open MAKE, "make |";
> foreach $line (<MAKE>) {
>    $count++;
>    my $percent = int(($count / $total) * 100);
> #  print "..$percent";
>    print $line;
> }
> 
> This waited until the end to print all the output. Although, 
> if I do something like 'make 
> | less' on the command line, the output is not buffered. So, 
> is Perl buffering the output 
> from MAKE in this case?


Close, but not quite.  perl is handing the data to your script as soon
as it
arrives from the make command.  The make command on the otherhand has
realised you
are not using a TTY, but are in fact directing the output to a pipe or
file, so
it buffers the contents internally.

Try the following.   

In one window, touch 'make.log', and then run 'tail -f make.log'

In another window, run 'make >> make.log'

If the output appears as it does when using less, then it is perl that
is
buffering the output, so add to your script:

# at the top
use IO::Handle;

# after the open
MAKE->autoflush(0);

If the output appears all at once when make has finished, as described
above, you
need to fool make into thinking you are a terminal.  Unfortunately, I'm
not familiar
with the perl package to make this so.

I don't have access to google or CPAN right now, so I can't provide the
package
name of a module which will help here.


--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
<http://learn.perl.org/> <http://learn.perl.org/first-response>


Reply via email to