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):