in reply to capture stdout and stderr from external command
#!/usr/bin/env perl use warnings; use strict; my %cmds; my ($count, $limit, $actmax) = (0, 10, 2); my ($cmdline) = 'sleep 1; echo BOOM'; # I think this command will work in Windows but not sure... sub spawncmd { my ($cmd) = @_; my $pid = open(my $of, '-|', $cmd) or die "open: $!"; ++$count; $cmds{$pid} = $of; warn "Spawned $pid"; return $pid; } sub cleancmd { my ($pid) = @_; die "error: unknown cmd pid: $pid" unless(exists $cmds{$pid}); my $of = delete $cmds{$pid}; print "$pid: $_" while(<$of>); close($of); } spawncmd($cmdline) for(1 .. $actmax); while(keys(%cmds) > 0){ my $pid = waitpid(-1, 0); die sprintf("error: pid $pid had exit code %d", $? >> 8) if($? != +0); cleancmd($pid); spawncmd($cmdline) if($count < $limit); }
This simplifies things by blocking until one of the running commands exits, then reading the command's output all at once before closing the pipe. Standard output and error streams are read together and not separated with a piped open. You didn't specify whether you wanted them together or separate. Parallel processing seems unnecessary in this situation but maybe you have performance requirements you didn't mention.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^2: capture stdout and stderr from external command
by Eliya (Vicar) on Nov 12, 2011 at 00:33 UTC | |
by juster (Friar) on Nov 12, 2011 at 02:55 UTC |