How do you capture stderr, stdout, and the exit code all at once, in Perl?

后端 未结 6 2197
情深已故
情深已故 2020-11-27 03:19

Is it possible to run an external process from Perl, capture its stderr, stdout AND the process exit code?

I seem to be able to do combinations of these, e.g. use ba

6条回答
  •  独厮守ぢ
    2020-11-27 03:48

    If you don't want the contents of STDERR, then the capture() command from IPC::System::Simple module is almost exactly what you're after:

       use IPC::System::Simple qw(capture system $EXITVAL);
    
       my $output = capture($cmd, @args);
    
       my $exit_value = $EXITVAL;
    

    You can use capture() with a single argument to invoke the shell, or multiple arguments to reliably avoid the shell. There's also capturex() which never calls the shell, even with a single argument.

    Unlike Perl's built-in system and backticks commands, IPC::System::Simple returns the full 32-bit exit value under Windows. It also throws a detailed exception if the command can't be started, dies to a signal, or returns an unexpected exit value. This means for many programs, rather than checking the exit values yourself, you can rely upon IPC::System::Simple to do the hard work for you:

     use IPC::System::Simple qw(system capture $EXIT_ANY);
    
     system( [0,1], "frobincate", @files);     # Must return exitval 0 or 1
    
     my @lines = capture($EXIT_ANY, "baznicate", @files);  # Any exitval is OK.
    
     foreach my $record (@lines) {
         system( [0, 32], "barnicate", $record);  # Must return exitval 0 or 32
     }
    

    IPC::System::Simple is pure Perl, has no dependencies, and works on both Unix and Windows systems. Unfortunately, it doesn't provide a way of capturing STDERR, so it may not be suitable for all your needs.

    IPC::Run3 provides a clean and easy interface into re-plumbing all three common filehandles, but unfortunately it doesn't check to see if the command was successful, so you'll need to inspect $? manually, which is not at all fun. Providing a public interface for inspecting $? is something which is on my to-do list for IPC::System::Simple, since inspecting $? in a cross-platform fashion is not a task I'd wish on anyone.

    There are other modules in the IPC:: namespace that may also provide you with assistance. YMMV.

    All the best,

    Paul

提交回复
热议问题