1

I currently have a perl script which I am trying to use to launch three (or more) php scripts each with a set of arguments provided from a database:

$sql = "SELECT id,url,added,lasttotal,lastsnapshot,speed,nextsnapshot FROM urls WHERE DATE(NOW()) > DATE(nextsnapshot)  LIMIT 0,3";
$sth = $dbh->prepare($sql);
$sth->execute or print "SQL Error: $DBI::errstr\n";

my ($urlID, $url, $added,$lastTotal,$lastSnapshot,$lastSpeed,$nextsnapshot);

$sth->bind_col(1, \$urlID);
$sth->bind_col(2, \$url);
$sth->bind_col(3, \$added);
$sth->bind_col(4, \$lastTotal);
$sth->bind_col(5, \$lastSnapshot);
$sth->bind_col(6, \$lastSpeed);
$sth->bind_col(7, \$nextsnapshot);

while ($sth->fetch) {
  $myexec = "php /usr/www/users/blah/blah/launch_snapshot.php '$url' $urlID '$added' $lastTotal '$lastSnapshot' $lastSpeed".'  /dev/null 2>&1 &';

  exec ($myexec)     or print  "\n Couldn't exec $myexec: $!";  
} 

I don't care about any results from the PHP scripts, I just need to start them all at once, or with a very small delay.

The fetch works properly and returns three unique sets of values. However, it never seems to get past launching the first php script. I don't get any error messages.

Any help would be most appreciated.

  • 2
    From the [official Perl FAQ](http://faq.perl.org): [How do I start a process in the background?](http://learn.perl.org/faq/perlfaq8.html#How-do-I-start-a-process-in-the-background-) ||| [How can I fire and forget a process in Perl?](http://stackoverflow.com/questions/2133910/how-can-i-fire-and-forget-a-process-in-perl) – daxim Jul 23 '12 at 11:54

2 Answers2

1

You could use fork or just system for that.

Using fork:

foreach($sth->fetch) {
  my $pid = fork();
  if($pid) { # Parent
    waitpid($pid, 0);
  } elsif ($pid == 0) { # A child
    $myexec = "...";
    exec($myexec) or print "\n Couldn't exec $myexec: $!";
    exit(0); # Important!
  } else {
    die "couldn't fork: $!\n";
  }
}

Using system:

foreach($sth->fetch) {
  $myexec = "...";
  system($myexec);
}
Qiau
  • 5,976
  • 3
  • 29
  • 40
  • Instead of `fork` and then `exec` a simple `system` would IMO be better. – dgw Jul 23 '12 at 09:07
  • 2
    -1 : How does this 'fire-and-forget'? `waitpid` will block until the child process completes. – Zaid Jul 23 '12 at 09:39
0

From perldoc -f exec

   exec LIST
   exec PROGRAM LIST
           The "exec" function executes a system command and never
           returns-- use "system" instead of "exec" if you want it to
           return.  It fails and returns false only if the command does
           not exist and it is executed directly instead of via your
           system's command shell (see below).

You want to system (or fork) not exec.

dgw
  • 13,418
  • 11
  • 56
  • 54