3

I have the following perl script (test.pl):

my $exit_code = system('./test.py');
print $exit_code."\n";

that is trying to capture the exit code from a python executable (test.py):

#!/bin/env python
import sys
sys.exit(2)

Directly running python executable returns 2, which is what I expected:

> ./test.py
> echo $?
2

However, running perl returns something different:

> perl test.pl
512

Why did perl capture a different exit code from python?

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
Hailiang Zhang
  • 17,604
  • 23
  • 71
  • 117
  • `512` *can't* be an exit code -- exit codes are single-byte, making the value too large to fit. – Charles Duffy Aug 19 '16 at 15:20
  • @CharlesDuffy: Perl's `system()` returns a rather funky version of an exit code. To get the actual value, you need to shift right by 8. So 512 is a valid return value which actually means 2 :-/ – Dave Cross Aug 19 '16 at 15:43
  • @DaveCross, yes, the answer specifying that already existed; my point was that what perl was capturing is clearly not a literal exit code at all. – Charles Duffy Aug 19 '16 at 15:47
  • @Charles Duffy, They are 16-bit in Windows – ikegami Aug 21 '16 at 18:14
  • @ikegami, ...if the OP hadn't been using shebangs on their scripts, I might have considered Windows a plausible platform, but as the situation is... – Charles Duffy Aug 21 '16 at 18:46
  • @Charles Duffy, I never said the OP was using Windows. Your comment wasn't even about the OP (since he used `exit(2)`, not `exit(512)`). I just pointed out an error in your claim. – ikegami Aug 21 '16 at 18:48
  • The context (of a UNIX platform) was present in the question to which the comment was applied. If I make a claim about `printf` on a question talking about C, it's very different from a claim about `printf` on a question talking about shell. I keep myself outside of win32-specific contexts for the most part, and when outside them have no intent of saying "except on Windows" every time I open my mouth. – Charles Duffy Aug 21 '16 at 18:53
  • Re "*The context (of a UNIX platform) was present in the question to which the comment was applied*", No, it wasn't. There's nothing unix-specific about the question. Executing the exact same program on Windows will give you exactly the same result. A reader would have no reason to believe the comment is unix-specific, and would thus be misinformed by your incorrect comment. You failed to take Win32 out of the context as you claim you do. If you had, I would not have needed to comment. – ikegami Aug 22 '16 at 16:44

2 Answers2

8

The child might not even have gotten to call exit. As such, system's returns value (aka $?) packs more information than just the exit parameter.

if    ( $? == -1  ) { die "Can't launch child: $!\n"; }
elsif ( $? & 0x7F ) { die "Child killed by signal ".( $? & 0x7F )."\n"; }
elsif ( $? >> 8   ) { die "Child exited with error ".( $? >> 8 )."\n"; }
else                { print "Child executed successfully\n"; }

This is documented.

ikegami
  • 367,544
  • 15
  • 269
  • 518
5

The documentation says "To get the actual exit value, shift right by eight".

Stefan Pochmann
  • 27,593
  • 8
  • 44
  • 107