문제

I needed to replace a radius autentification script (for PPPoE connections). This is a heavily used service that runs 24/7, so to test the new script I injected a small code in the begining of the original script to fork a new process that called the new script (without the danger of breaking something if the new script failes). This is the injected code:

$pid =  fork();
if($pid == 0)
{
    my $now_string = POSIX::strftime "%a %b %e %H:%M:%S %Y", localtime;
    open(FILE,">>/new_log_file.log");
    `/new_script_path/new_script.pl @ARGV`;
    if ($? == 0)
    {
        print FILE "[".$now_string."] Chiled executed succesfuly\n";
    } elsif($? == -1)
    {
        print FILE "[".$now_string."] FAILED to execute\n";
    } elsif($? & 127)
    {
       printf FILE "[".$now_string."] child died with signal %d, %s coredump\n", ($? & 127), ($? & 128) ? 'with' : 'without';
    } else
    {
       printf FILE "[".$now_string."] child exited with value %d\n", $? >> 8;
    }
    close(FILE);
    exit;
}

Unfortunately this failed to execute the new script and in the log files I had this message:

"[Mon Feb 27 09:25:10 2012] child exited with value 5"

Without shifting the bits, the value of $? is 1280;

The new script works as expected if I manualy call it.

What does status code 5 means ? How can I debug the command in the backtick to find out what's going wrong ?

도움이 되었습니까?

해결책

After a lot of search I finaly found the way to debug it. Look at the new code:

my $now_string = POSIX::strftime "%a %b %e %H:%M:%S %Y", localtime;
open(FILE,">>/new_log_file.log");
$output = `/new_script_path/new_script.pl @ARGV 2>&1`;
if ($? == 0)
{
    print FILE "[".$now_string."] Chiled executed succesfuly\n";
} elsif($? == -1)
{
    print FILE "[".$now_string."] FAILED to execute\n";
} elsif($? & 127)
{
   printf FILE "[".$now_string."] child died with signal %d, %s coredump\n", ($? & 127), ($? & 128) ? 'with' : 'without';
} else
{
   printf FILE "[".$now_string."] child exited with value %d (%d) [ %s ]\n", $? >> 8, $?, $output;
}
close(FILE);

What I did is capture the STDOUT and STDERR of the command in the backtick (documentation here ), and print it in the log file.

Now I found this message in the log file, and found what was wrong:

[Mon Feb 27 09:40:41 2012] child exited with value 2 (512) [ Can't locate lib.pl in @INC (@INC contains: [long output removed] ) at /new_script_path/new_script.pl line 30.

I answered the question, of how to debug it ( the strange part is that with this new code the status code is 2 not 5 )

In the hope this will help others I will tell you what were my 2 mistakes (please correct me if i'm wrong):

  1. I loaded a lib without the full path.
  2. When I manualy tested the new script, I only called him from the same directory where it resides.
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top