4

I want a progress indicator that takes the output of a Perl

   system('make')

and for each line output to STDOUT from the make command, I want to output a dot as a progress indicator. Unfortunately, I'm using the Term::ReadLine::Gnu Perl mod.

How do I redirect STDOUT to capture and count the lines as the make command is running?

bitbucket
  • 1,171
  • 1
  • 9
  • 20
  • You may also find [Term::ProgressBar](http://search.cpan.org/perldoc/Term::ProgressBar) of use. – Ether May 19 '11 at 00:37

2 Answers2

7
#!/usr/bin/perl

my $command = "make";

open (my $cmd, "$command |");
while(<$cmd>){
  print ".";
}
print "\n";
wespiserA
  • 3,131
  • 5
  • 28
  • 36
  • 3
    I recommend using a three-arg `open` for this: `open my $cmd, '-|', $command or die $!;` This is safer and more efficient. – friedo May 19 '11 at 01:03
  • good advice, I use the three-arg version exclusively for files, why not pipes as well? Also, this might be a case where using print over die may have its advantages. – wespiserA May 19 '11 at 01:11
  • 3
    You'll want to autoflush STDOUT otherwise it'll wait for a whole line of dots before printing. `use IO::Handle; STDOUT->autoflush(1)` – Schwern May 19 '11 at 06:20
  • yeah, add $outStatus=$?; inside the while loop, then after the loop add a line like print "$command was SUCCESSFUL\n" if ($outStatus ~~ 0); – wespiserA May 19 '11 at 20:28
4
make >& >(while read f; do echo -n .; done; echo)

Obviously this is a shell solution, but a dot as a progress indicator is a dot.

You could of course stick a tee in there to save a copy of the make to file in case of problems.

Since you didn't seem to like (neither upvoted or accepted) the shell solution for some unexplained reason, here is a pure perl one:

if (open(X,"make|")) { local($|)=1; while(<X>) { print "."; } close(X); print "\n";}
Seth Robertson
  • 30,608
  • 7
  • 64
  • 57