smith111 has asked for the wisdom of the Perl Monks concerning the following question:

I can use $ret=system("prog"); to get the return value from the shell, or I can use @out=`prog`; to get the stdout from the command. How can I get everything?

for example; ($ret,@out,@err) = execthis("prog");

is it possible?

Replies are listed 'Best First'.
Re: executing an external program
by shmem (Chancellor) on Jun 21, 2006 at 17:01 UTC
    See IPC::Open3 for capturing STDOUT and STDERR. Note that you should waitpid on the value returned from open3 and look into $? to get the exit status.

    _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                  /\_¯/(q    /
    ----------------------------  \__(m.====·.(_("always off the crowd"))."·
    ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
Re: executing an external program
by Fletch (Bishop) on Jun 21, 2006 at 16:53 UTC

    $? will contain the exit status from the last child process (including backticks). See also IPC::Run.

      It's also worth checking out IPC::Run3. The documentation includes a comparison of IPC::Run3 to:

      • system()
      • qx''
      • open "...|"
      • open "|..."
      • open2()
      • open3()
      • IPC::Run

      -xdg

      Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.

Re: executing an external program
by ambrus (Abbot) on Jun 21, 2006 at 22:37 UTC
Re: executing an external program
by Moron (Curate) on Jun 22, 2006 at 14:35 UTC
    something like...
    use IPC::Open3; use POSIX ":sys_wait_h"; package SysCall3; sub exec{ my $self = shift; my $command = shift; $self = {}; my $pid = open3 my $wh, my $rh, my $eh, $command; $self -> { EXITCODE } = $?; close $wh; $self -> { STDOUT } = <$rh>; close $rh; $self -> { STDERR } = <$eh>; close $eh; waitpid $pid,0; return bless $self; } sub getinfo( my $self = shift; return $self -> { shift() }; } 1;
    example:
    use SysCall3; my $nasty = SysCall3 -> exec( 'bigNastyProgram' ); for my $err ( $nasty -> getinfo( 'STDERR' ) ) { # process the error output print STDERR $err; } for my $out ( $nasty -> getinfo ('STDOUT' ) ) { # process the stdout print $out; } my $code = $nasty -> getinfo( 'EXITCODE' ); # process return code exit $code; # if wanting to pass control back to the o/s
    Can also have the exec method leave the filehandles unread and store them in the object hash and another method be used to read from them. In that case, the pid should also be stored in the hash and the close/waitpid need to be invoked whenever needed to prevent zombies.

    -M

    Free your mind

      Thank you Moron, you have freed my mind.