8

I have a Perl script which calls another script. The Perl script should be propagating the script's return code but seems to be returning zero to its caller (a Java application) desipte the explicit call to exit $scriptReturnCode.

Code and output as follows (I realise that <=> could/should be != but that's what I have):

print "INFO: Calling ${scriptDirectory}/${script} ${args}"
$scriptReturnCode = system("${scriptDirectory}/${script} ${args}");

if ( $scriptReturnCode <=> 0 ) {
        print "ERROR: The script returned $scriptReturnCode\n";
        exit $scriptReturnCode;
} else {
        print "INFO: The script returned $scriptReturnCode.\n";
        exit 0;
}

The output I have from my Java is:

20/04/2010 14:40:01 - INFO: Calling /path/to/script/script.ksh arg1 arg2 
20/04/2010 14:40:01 - Could not find installer files <= this is from the script.ksh    
20/04/2010 14:40:01 - ERROR: The script returned 256
20/04/2010 14:40:01 - Command Finished. Exit Code: 0 <= this is the Java app.

2 Answers 2

10

You need to shift the return code from system() call by 8 bits.

E.g. $exit_value = $? >> 8; # In your script the $? is $scriptReturnCode

From http://perldoc.perl.org/perlfaq8.html :

system() runs a command and returns exit status information (as a 16 bit value: the low 7 bits are the signal the process died from, if any, and the high 8 bits are the actual exit value

A more expanded code checking for coredumps as well could look like this:

system();
if ($? == -1) {
    print "failed to execute: $!\n";
} elsif ($? & 127) {
    printf "child died - signal %d, %s coredump\n",
           ($? & 127), ($? & 128) ? 'with' : 'without';
} else {
    printf "child exited with value %d\n", $? >> 8;
}

UPDATE: As per ysth's excellent reminder, the exit codes are truncated at 8 (low) bits, so returning 256 instead of the intended 1 ends up as 0. Similarly, returning 257 ends up as 1.

Sign up to request clarification or add additional context in comments.

2 Comments

Assume you mean shift as in $scriptReturnCode = $scriptReturnCode >> 8;
Ideally, add explicitly that exit codes are truncated at 8 (low) bits, so returning 256 instead of the intended 1 ends up as 0. Similarly, returning 257 ends up as 1, etc.
1

If capturing $? and shifting its value is too much trouble to remember, you can simplify that code by using IPC::System::Simple, which enhances system() and backticks with more error checking and diagnostics, e.g.:

use IPC::System::Simple qw(run EXIT_ANY);

my $command = "${scriptDirectory}/${script} ${args}";
print "INFO: Calling $command\n";

# runs command through a shell first; does not die on any exit value
run(EXIT_ANY, $command);
my $scriptReturnCode = $IPC::System::Simple::EXITVAL;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.