简体   繁体   English

Perl system()命令的奇怪行为

[英]Odd behavior with Perl system() command

Note that I'm aware that this is probably not the best or most optimal way to do this but I've run into this somewhere before and I'm curious as to the answer. 请注意,我知道这可能不是执行此操作的最佳或最佳方法,但我之前曾遇到过此问题,并且对答案感到好奇。

I have a perl script that is called from an init that runs and occasionally dies. 我有一个从运行的init调用的perl脚本,它有时会死掉。 To quickly debug this, I put together a quick wrapper perl script that basically consists of 为了快速调试,我整理了一个快速包装的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...
}

Fire this up from the command line and it runs fine and as expected. 从命令行启动它,它运行正常且符合预期。 command.pl is called and the script basically halts there until the child process dies then goes around again. command.pl被调用,脚本基本上停在那里,直到子进程死掉,然后再次运行。

However, when called from a start script (actually via start-stop-daemon), the system command returns immediately, leaving command.pl running. 但是,当从启动脚本(实际上是通过start-stop-daemon)调用时,系统命令立即返回,而command.pl仍在运行。 Then it goes around for another go. 然后它又绕了下去。 And again and again. 一遍又一遍。 (This was not fun without the sleep command.). (如果没有sleep命令,这不好玩。) ps reveals the parent of (the many) command.pl to be 1 rather than the id of the wrapper script (which it is when I run from the command line). ps揭示(许多)command.pl的父代为1,而不是包装器脚本的ID(当我从命令行运行时是该ID)。

Anyone know what's occurring? 有人知道发生了什么吗?

Maybe the command.pl is not being run successfully. 也许command.pl没有成功运行。 Maybe the file doesn't have execute permission (do you need to say perl command.pl ?). 也许该文件没有执行权限(您需要说一下perl command.pl吗?)。 Maybe you are running the command from a different directory than you thought, and the command.pl file isn't found. 也许您从与您想象的目录不同的目录中运行命令,但找不到command.pl文件。

There are at least three things you can check: 您至少可以检查三件事:

  1. standard error output of your command. 命令的标准错误输出。 For now you are swallowing it by saying 2>&1 . 现在,您通过说2>&1吞噬它。 Remove that part and observe what errors the system command produces. 卸下该部件,并观察system命令产生什么错误。
  2. the return value of system . system的返回值。 The command may run and system may still return an exit code, but if system returns 0, you know the command was successful. 该命令可能会运行,并且system仍可能返回退出代码,但是如果system返回0,则表示命令已成功执行。
  3. Perl's error variable $! Perl的错误变量$! . If there was a problem, Perl will set $! 如果有问题,Perl将设置$! , which may or may not be helpful. ,这可能会或可能不会有帮助。

To summarize, try: 总结一下,尝试:

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

Update: if multiple instance of the command keep showing up in your ps output, then it sounds like the program is forking and running itself in the background. 更新:如果该命令的多个实例在您的ps输出中持续显示,则听起来该程序在后台派生并自行运行。 If that is indeed what the command is supposed to do, then what you do NOT want to do is run this command in an endless loop. 如果确实是该命令应该执行的操作,则您希望执行的操作是无限循环地运行此命令。

Perhaps when run from a deamon the "system" command is using a different shell than the one used when you are running as yourself. 也许从守护进程运行时,“系统”命令使用的外壳与您自己运行时使用的外壳不同。 Maybe the shell used by the daemon does not recognize the >& construct. 守护程序使用的shell可能无法识别>&构造。

如果可以,请尝试使用exec("...")函数代替system("...")

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM