Perl system()命令的奇怪行为

时间:2012-11-01 18:53:59

标签: perl system infinite-loop init.d

请注意,我知道这可能不是最佳或最佳的方法,但我之前遇到过这种情况,我很好奇答案。

我有一个从运行的init调用的perl脚本,偶尔会死掉。为了快速调试这个,我整理了一个基本上由

组成的快速包装perl脚本
#$path set from library call.    
while(1){
  system("$path/command.pl " . join(" ",@ARGV) . " >>/var/log/outlog 2>&1");
  sleep 30; #Added this one later. See below...
}

从命令行启动它,它运行正常并且符合预期。调用command.pl并且脚本基本上停止,直到子进程死亡然后再次出现。

但是,从启动脚本(实际上通过start-stop-daemon)调用时,系统命令立即返回,使command.pl运行。然后它又转了一圈。一次又一次。 (没有睡眠命令,这并不好玩。) ps将(很多)command.pl的父元素显示为1,而不是包装器脚本的id(当我从命令行运行时)。

任何人都知道发生了什么?

3 个答案:

答案 0 :(得分:2)

可能command.pl未成功运行。也许该文件没有执行权限(您是否需要说perl command.pl?)。也许您从不同的目录运行命令,并且找不到command.pl文件。

至少有三件事可以检查:

  1. 命令的标准错误输出。现在你只是说2>&1吞下它。删除该部分并观察system命令产生的错误。
  2. system的返回值。命令可能会运行,system可能仍会返回退出代码,但如果system返回0,则表示命令成功。
  3. Perl的错误变量$!。如果出现问题,Perl会设置$!,这可能会有所帮助。
  4. 总结一下,试试:

    my $ec = system("command.pl >> /var/log/outlog");
    if ($ec != 0) {
        warn "exit code was $ec, \$! is $!";
    }
    

    更新:如果命令的多个实例一直显示在ps输出中,那么听起来好像程序正在分支并在后台运行。如果这确实是命令应该做的事情,那么你做 NOT 想要做的就是在无限循环中运行这个命令。

答案 1 :(得分:0)

也许从deamon运行时,“system”命令使用的shell不同于您自己运行时使用的shell。也许守护程序使用的shell无法识别>&构造

答案 2 :(得分:-3)

如果适用于system("..."),请尝试exec("...")功能,而不是{{1}}。