1

我需要替换一个半径认证脚本(用于 PPPoE 连接)。这是一个 24/7 运行的频繁使用的服务,所以为了测试新脚本,我在原始脚本的开头注入了一个小代码来派生一个调用新脚本的新进程(如果新脚本没有破坏某些东西的危险脚本失败)。这是注入的代码:

$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;
}

不幸的是,这无法执行新脚本,并且在日志文件中我收到了以下消息:

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

在不移动位的情况下,$ 的值?是 1280;

如果我手动调用它,新脚本将按预期工作。

状态码 5 是什么意思?如何调试反引号中的命令以找出问题所在?

4

1 回答 1

2

经过大量搜索,我终于找到了调试它的方法。看看新代码:

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

我所做的是在反引号(此处的文档)中捕获命令的 STDOUT 和 STDERR,并将其打印在日志文件中。

现在我在日志文件中找到了这条消息,发现出了什么问题:

[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.

我回答了如何调试它的问题(奇怪的是,这个新代码的状态码是 2 而不是 5)

希望这对其他人有帮助,我会告诉你我的两个错误是什么(如果我错了,请纠正我):

  1. 我加载了一个没有完整路径的库。
  2. 当我手动测试新脚本时,我只从它所在的同一目录中调用了他。
于 2012-02-27T09:14:25.697 回答