$output = `$cmd 2>&1` #### use strict; use IO::Select; use POSIX; pipe(STDOUT_READ, STDOUT_WRITE) || die; pipe(STDERR_READ, STDERR_WRITE) || die; my $pid = fork(); die unless (defined($pid)); if ($pid == 0) { close STDOUT_READ; close STDERR_READ; open(STDOUT, ">&STDOUT_WRITE"); open(STDERR, ">&STDERR_WRITE"); close STDOUT_WRITE; close STDERR_WRITE; exec $cmd; POSIX::_exit(1); } my $stdout_collected = ""; my $stderr_collected = ""; close STDOUT_WRITE; close STDERR_WRITE; my $sel = IO::Select->new(); $sel->add(\*STDOUT_READ); $sel->add(\*STDERR_READ); my $remaining = 2; while ($remaining > 0) { my @ready = $sel->can_read(); for my $r (@ready) { my $got; if (sysread($r, $got, 1024) == 0) { close $r; $remaining--; } ($r == \*STDOUT_READ) ? $stdout_collected : $stderr_collected .= $got; } } undef $sel; waitpid $pid, 0; # stdout is collected in $stdout_collected # stderr is collected in $stderr_collected