0

how can we capture the exit code correctly when we call a command via 'system'? from the testcase below i consistently capture "-1" which the expectation is "0" for code1 and "1" for code2.

test1.pl

use feature qw(say);
use strict;

my $code = system("./test2.pl 0");
say "code1  = $code";
system("./test2.pl 0");
say "code1' = $?";

$code = system("./test2.pl 1");
say "code2  = $code";
system("./test2.pl 1");
say "code2' = $?";

test2.pl

use feature qw(say);

use strict;

say "arg = @ARGV[0]";
my $exit_code = @ARGV[0];
say "this is a dummy script which exit with $exit_code";
exit $exit_code;

Output:

% ./project_r/test.pl
code1 = -1
code1' = -1
code2 = -1
code2' = -1
3
  • % ./project_r/test.pl code1 = -1 code1' = -1 code2 = -1 code2' = -1 Commented Jun 23, 2020 at 15:26
  • i am running the perl script in csh Commented Jun 23, 2020 at 15:35
  • Re "i am running the perl script in csh", Irrelevant. system always uses /bin/sh (except on Windows), or no shell at all when it can parse the command itself (like in your case). Commented Jun 23, 2020 at 15:39

2 Answers 2

3

As per the documentation for system, -1 indicates there was a problem trying to execute the command, and that the error message is found in $!.

system(...);
die("Can't run test2: $!\n") if $? == -1;
die("test2 killed by signal ".( $? & 0x7F )."\n") if $? & 0x7F;
die("test2 exited with error ".( $? >> 8 )."\n") if $? >> 8;
say("Child completed successfully.");

As you can see by the lack of output of this is a dummy, your program never ran.

Likely culprits are:

  • The path doesn't refer to an existing file.
  • The file isn't executable.

A missing shebang (#!) line could render a file non-executable, but I'm presuming you simply left out the shebang lines from your snippets for conciseness (since ./project_r/test.pl wouldn't run otherwise).

I'm also assuming that the difference in the name of the file you posted (test1.pl) and the file you executed (test.pl) isn't relevant.

My best guess is that test2.pl is in the same directory as test.pl/test1.pl, which isn't the current directory but a subdircetory of the current directory named project_r.

Fix:

use FindBin qw( $RealBin );

my $code = system("$RealBin/test2.pl", "0");
Sign up to request clarification or add additional context in comments.

2 Comments

it is working after i fix the code as you suggested. just that for the case i expecting it return 1 but i get 256 instead. any clue on this?
See the docs for system or the first code snippet in my answer.
1

Note that if you are going to run other Perl programs from a Perl program, you need to use the same settings. Otherwise you might run into situations where you are using a different perl with your parent perl's settings:

Your current Perl is in $^X:

system $^X, 'test2.pl', '0';

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.