1

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. To quickly debug this, I put together a quick wrapper perl script that basically consists of

#$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.

However, when called from a start script (actually via start-stop-daemon), the system command returns immediately, leaving command.pl running. Then it goes around for another go. And again and again. (This was not fun without the sleep command.). 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).

Anyone know what's occurring?

  • Looks like something in the init script is passing an & in as part of the @ARGV. It seems that this is an error in the init script, probably a cut & paste error. Next I need to figure if fixing this will break anything else (since the command.pl does something similar itself). – user1792286 Nov 13 '12 at 22:52

3 Answers3

2

Maybe the command.pl is not being run successfully. Maybe the file doesn't have execute permission (do you need to say perl command.pl?). Maybe you are running the command from a different directory than you thought, and the command.pl file isn't found.

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. Remove that part and observe what errors the system command produces.
  2. the return value of system. The command may run and system may still return an exit code, but if system returns 0, you know the command was successful.
  3. Perl's error variable $!. If there was a problem, Perl will set $!, 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. 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.

mob
  • 117,087
  • 18
  • 149
  • 283
0

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.

JoelFan
  • 37,465
  • 35
  • 132
  • 205
  • 1
    Joel, that was one thing I was considering. I know the >&1 syntax was not usable when I first started scripting so maybe it's interpreting it as an & thing. Path should be taken care of since I use findbin to generate it (it's in the same directory). I can guarantee that the program does not fork itself. – user1792286 Nov 01 '12 at 21:38
  • Perhaps command.pl is not executable or does not begin with "#!/usr/bin/perl – Liudvikas Bukys Nov 02 '12 at 02:38
  • Also you say you used findbin but I don't see you using $Bin – Liudvikas Bukys Nov 02 '12 at 02:38
  • Sorry, the actual code uses $path which is set by Findbin earlier. Verified that this is command.pl is actually running since multiple instances of this caused OOM errors before the sleep() was added. – user1792286 Nov 02 '12 at 13:43
-3

Instead of system("..."), try exec("...") function if that works for you.

2teez
  • 1
  • 1