($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";