Getting Perl to return the correct exit code

偶尔善良 提交于 2021-01-21 12:17:11

问题


I'm using Perl 5.10.1 on Ubuntu 11.04. I want Perl to execute a shell script and exit with the same code the shell script exits. But this isn't working for me ...

    system($runCmd) or die("Failed to run \"$runCmd\": $!");

I have confirmed that running the "$runCmd" by itself returns an exit code of 255, but the "die" clause isn't getting invoked. How do I exit with the correct code or at least fail for non-success codes?

Another minor requirement is that I want the output from $runCmd to be printed to the screen.


回答1:


As perldoc -f die says, die doesn't give a specific exit code (only a nonzero exit code). To get what you want, you'll need something like:

my $exit_code=system($runCmd);

if($exit_code!=0)
{
  print "Command $runCmd failed with an exit code of $exit_code.\n";
  exit($exit_code >> 8);
}
else
{
  print "Command $runCmd successful!\n";
}



回答2:


If system returns 255, you need an and conditional.

system returns zero on successful execution. Also, die will modify your script's exit code. Instead warn and return the last exit code like this:

system($cmd) and do {
    warn "Failed to run $cmd. Exit code is $?";
    exit $? >> 8;
};

In order to catch the program's output, use the backtick (`) operator:

my $output = `$cmd`;

if ($?) {
   warn ...;
   exit $? >> 8;
}

The backtick operator only captures STDOUT, so for all error messages (which usually go to STDERR) to be captured, modify $cmd and append 2>&1 to it.

Notice the right shift by eight bits on the $? global.


Credits go to @musiKk: The perl documentation on system() states how to properly retrieve the actual exit status.




回答3:


  system($runCmd) or die("Failed to run \"$runCmd\": $!");

Unlike most Perl functions, system returns false when it succeeds and true when it fails. This is completely backwards I know but it is just how it is.

You need "system() and" not "system() or". And you probably want $? not $!, although this can sometimes be tricky.

I have a minor aversion to

system(...)                           && die

because it screws up all the rest of || die’s that normally make a continuous vertical double margin over on the right, I sometimes write

system(...) == 0                      || die

so that they all line up correctly again.




回答4:


If system()'s seeming backwardness bothers you, you can always make it more palatable by doing something like:

my $err = system '/something/that/may/not/work';
if ($err) {
    warn "@{[$! || 'undefined error']}\n";
    exit $err >> 8;
}

Your $runCmd, BTW, if it prints to the screen (and this is run from the command line and you haven't redirected the output, etc.) will print to the screen. It's just that IT will print it to the screen. Perl won't be responsible for that or know (or care) what it's printing. If that's all you want, and you don't want to systematically analyse or manipulate the output of $runCmd, you're golden. Try it:

perl -e "system 'ls -Fahl'"

It also won't interfere with your $runCmd's STDOUT either. That'll go to your terminal too. For instance:

$ perl -e "system 'ls -Fahl /dev/null/something' and die qq(fail: $! >> 8 == @{[$! >> 8]})"
ls: /dev/null/something: Not a directory
fail: 26205 >> 8 == 102 at -e line 1.


来源:https://stackoverflow.com/questions/7080434/getting-perl-to-return-the-correct-exit-code

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