Reputation: 1138
I am using system
to call an external application and I need to interpret its exit code.
I know that system
returns the exit code from the command multiplied by 256, but when in foo.bat
I write exit 256
the result is zero.
Why is this happening?
Upvotes: 2
Views: 1588
Reputation: 385506
Windows uses 32-bit exit codes, so exit 256
is perfectly valid.
>cmd /c exit 256
>echo %ERRORLEVEL%
256
However, Perl only keeps the least significant 8 bits.
>perl -e"system 'exit 256'; CORE::say $?>>8"
0
>perl -e"system 'exit 266'; CORE::say $?>>8"
10
This is a Perl defect for which there's no good reason. If you use Win32::Process instead of system
, you can obtain the correct exit code.
>perl -MWin32::Process=NORMAL_PRIORITY_CLASS,INFINITE -e"Win32::Process::Create(my $proc, $ENV{COMSPEC}, 'cmd /c exit 256', 0, NORMAL_PRIORITY_CLASS, '.') or die $^E; $proc->Wait(INFINITE); $proc->GetExitCode(my $exit_code); CORE::say $exit_code;"
256
Upvotes: 5
Reputation: 21
All the possibilities of failure can be obtained by examining $?
.
$exit_val = $? >> 8;
$signal = $? & 127;
$dumped_core = $? & 128;`
To quote from perldoc perlvar :
$CHILD_ERROR
$?
The status returned by the last pipe close, backtick (``) command, successful call to
wait()
orwaitpid()
, or from thesystem()
operator. This is just the 16-bit status word returned by the traditional Unixwait()
system call (or else is made up to look like it). Thus, the exit value of the subprocess is really ($? >> 8
), and$? & 127
gives which signal, if any, the process died from, and$? & 128
reports whether there was a core dump.
Upvotes: -1
Reputation: 126722
The return code is a single-byte value from zero to 255.
The most reliable way to check the status of a system
call is to examine $?
. It's documented in perldoc perlfunc
like this
if ($? == -1) {
print "failed to execute: $!\n";
}
elsif ($? & 127) {
printf "child died with signal %d, %s coredump\n",
($? & 127), ($? & 128) ? 'with' : 'without';
}
else {
printf "child exited with value %d\n", $? >> 8;
}
Upvotes: 2