($result, $exitcode) = run_w_progress(1, 'for i in `seq -w 4`; do sleep 3; /bin/echo $i; done');
####
Result:
1
2
3
4
Exitcode:0
finishing ...
####
($result, $exitcode) = run_w_progress(1, '/bin/echo -e "foo\nbar"');
####
Result:
foo
Exitcode:0
finishing ...
####
#!/usr/bin/perl
use strict;
use warnings;
use POSIX ":sys_wait_h";
use IO::Select;
use IO::Handle;
my ($result, $exitcode) = run_w_progress(1, 'for i in `seq -w 4`; do sleep 3; /bin/echo $i; done');
print "Result:\n",$result,"\nExitcode:",$exitcode,"\n";
($result, $exitcode) = run_w_progress(1, '/bin/echo -e "foo\nbar"');
print "Result:\n",$result,"\nExitcode:",$exitcode,"\n";
sub run_w_progress {
my ($sleep, $cmd) = @_;
my($reader, $writer);
pipe $reader, $writer;
my($reader2, $writer2);
pipe $reader2, $writer2;
$writer->autoflush(1);
$writer2->autoflush(1);
my @watch = qw(| / - + \ | / - \ |);
my $pos = 0;
$|++;
if ( fork()) {
my $kid;
my $output = '';
my $exitval;
my $c=0;
my $handles = IO::Select->new();
$handles->add($reader, $reader2);
do {
sleep $sleep;
my @fhs;
while (@fhs = $handles->can_read(0)) {
for my $fh (@fhs){
if (fileno($fh) == fileno($reader)) {
my $line = scalar <$reader>;
$output .= $line;
}
else {
$exitval = scalar <$reader2>;
chomp $exitval;
}
}
}
print "\r",'|'x$pos,$watch[$c++];
if ($c == 10) {
$c=0;
$pos++;
}
$kid = waitpid(-1, WNOHANG);
} until $kid > 0;
print "|\n";
return ($output, $exitval);
}
else {
open(my $pipe, '-|', $cmd);
while (<$pipe>) {
# pass output line to parent
print $writer $_;
}
close $pipe;
close $writer;
# pass exit value to parent
print $writer2 $?>>8, "\n";
close $writer2;
exit 0;
}
}
print "finishing ...\n";