A piggy bank of commands, fixes, succinct reviews, some mini articles and technical opinions from a (mostly) Perl developer.

Jump to

Quick reference

Showing posts with label ipc3. Show all posts
Showing posts with label ipc3. Show all posts

Run an external command from Perl, capturing both the output and the exit value


# This is how to run an external command from Perl,
# capturing both the output and the exit value

sub run_external_command {
    my ($self, $command) = @_;
    $self->logger->debug("Running command: $command");

    my $output = '';
    $command .= ' 2>&1 | '; # capture all output
    open(my $capture, $command);
    {
        local $/ = undef;
        $output = <$capture>;
    }
    close($capture);
    chomp($output);

    my $exit_value = ${^CHILD_ERROR_NATIVE} >> 8;
    $self->logger->debug("Exit value of command: '$exit_value'");
    $self->logger->debug("Output of command: '".($output || '[no output]')."'");

    return ($exit_value, $output);
}

This is another way:

use IPC::Open3;

sub run_external_command_2 {
  local (*my_in, *my_out, *my_err);

  my $command = "some command here that might error";
  my $pid = open3(\*my_in, \*my_out, \*my_err, $command) or die($!);

  close(my_in);
  my $std_out = do { local $/; };close(my_out);
  my $std_err = do { local $/; };close(my_err);

  waitpid($pid, 0);
  my $exit_code = $? >> 8;

  return { exit_code => $exit_code, std_out => $std_out, std_err => $std_err };
}