How to test the exit status from IPC::Run3

微笑、不失礼 提交于 2019-12-01 13:02:36

A few points to go through.

First, for the direct question, the IPC::Run3 documentation tells us that

run3 throws an exception if the wrapped system call returned -1 or anything went wrong with run3's processing of filehandles. Otherwise it returns true. It leaves $? intact for inspection of exit and wait status.

The error you ask about is of that kind and you need to eval the call to catch that exception

use warnings 'all';
use strict;
use feature 'say';

my ($stdout, $stderr);

my @cmd = ("ls", "-l");

eval { run3 \@cmd, \undef, \$stdout, \$stderr };
if    ( $@        ) { print "Error: $@";                     }
elsif ( $? & 0x7F ) { say "Killed by signal ".( $? & 0x7F ); }
elsif ( $? >> 8   ) { say "Exited with error ".( $? >> 8 );  }
else                { say "Completed successfully";          }

You can now print your own messages inside if ($@) { } block, when errors happen where the underlying system fails to execute. Such as when a non-existing program is called.

Here $@ relates to eval while $? to system. So if run3 didn't have a problem and $@ is false next we check the status of system itself, thus $?. From docs

Note that a true return value from run3 doesn't mean that the command had a successful exit code. Hence you should always check $?.

For variables $@ and $? see General Variables in perlvar, and system and eval pages.

A minimal version of this is to drop eval (and $@ check) and expect the program to die if run3 had problems, what should be rare, and to check (and print) the value of $?.

A note on run3 interface. With \@cmd it expects @cmd to contain a command broken into words, the first element being the program and the rest arguments. There is a difference between writing a command in a string, supported by $cmd interface, and in an array. See system for explanation.

Which alternative would suit you best depends on your exact needs. Here are some options. Perhaps first try IPC::System::Simple (but no STDERR on the platter). For cleanly capturing all kinds of output Capture::Tiny is great. On the other end there is IPC::Run for far more power.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!