silkAdmin
silkAdmin

Reputation: 4810

Run shell command asynchronously using PHP and node

I need to execute a shell program that will run a rather long process and I dont want to wait until that process has ended for my PHP script to carry on execution. So far i tried:

1:Pure PHP

exec("longCommand &");

2:Node and php

exec("/usr/local/bin/node nodeLauncher.js &");

Node:

var spawn = require('child_process').spawn,
  proc = spawn('longCommand', ['&']);

console.log('return');

In both cases the script carry on execution only after the "longCommand" has returned. Am I doing something wrong?

Upvotes: 0

Views: 2257

Answers (3)

i am ArbZ
i am ArbZ

Reputation: 69

Although my filenames used here seems weird, why dont try to look at my working prototype of the raw code below... i can't post the other parts dude as I have attached to it my private DB passwords..eheheh


LINK: http://affiliateproductpromotions.net/sml1r.php


<?php
if(isset($_GET['y']))
$y =false;
else $y =true;
if(isset($_GET['count']))
{
echo getCount($_GET['f'],$y);
exit;
}

if(isset($_GET['stop']) && $_GET['stop']=='true')
{
$fr=fopen("huhu.txt","w");
fwrite($fr,"<script>document.getElementById('send').disabled=false;document.getElementById('stop').disabled=true;document.getElementById('process').innerHTML='<b style=color:GREY>Current Status: Stopped!</b>';document.getElementById('stop').style='width:90px;color:LIGHTYELLOW;background-color:GREY';document.getElementById('send').style='width:90px;color:LIGHTYELLOW;background-color:BLUE';</script>");
fclose($fr);

include('../semail/killexec.php');
sleep(2);
//exit;
}
else
{

 header("Connection: close");
 ignore_user_abort(); // optional
 ob_start();
 echo ('Text the user will see');
 $size = ob_get_length();
 header("Content-Length: $size");

function run_in_background($Command, $Priority = 0)
   {
       if($Priority)
           $PID = shell_exec("nohup nice -n $Priority $Command > /dev/null 2>&1 & echo $!");
       else
           $PID = shell_exec("nohup $Command > /dev/null 2>&1 & echo $!");
       return($PID);
   }

  function is_process_running($PID)
   {
       exec("ps $PID", $ProcessState);
       return(count($ProcessState) >= 2);
   }



 //ob_end_clean();


echo("Running hmmsearch. . .");

$ps = run_in_background("hmmsearch $hmmfile $fastafile > $outfile");
$fpf = fopen("pid.txt","w");
fwrite($fpf,exec('ps '.$ps));
fclose($fpf);
while($i<=getCount())
{
$fp2 = fopen("sent1email.txt","w");
fwrite($fp2,getEmailSent($i));
fclose($fp2);
$fp = fopen("haha.txt","w");
fwrite($fp,"$i\n");
//     echo("<br> [ ".$i++." ] ");
//       ob_flush(); flush();

$i++;
sleep(2); 

if($i==getCount())
{
$fr=fopen("huhu.txt","w");
fwrite($fr,"<script>document.getElementById('send').disabled=false;document.getElementById('stop').disabled=true;document.getElementById('process').innerHTML='<b style=color:GREY>Current Status: Finished Sending!</b>';document.getElementById('stop').style='width:90px;color:LIGHTYELLOW;background-color:GREY';document.getElementById('send').style='width:90px;color:LIGHTYELLOW;background-color:BLUE';</script>");

fclose($fr);
sleep(1);
include('../semail/killexec.php');
}
if($i<getCount())
{
$fr=fopen("huhu.txt","w");
fwrite($fr,"<script>document.getElementById('send').disabled=true;document.getElementById('stop').disabled=false;document.getElementById('process').innerHTML='<b style=color:GREY>Current Status: Sending...</b>';document.getElementById('send').style='width:90px;color:LIGHTYELLOW;background-color:GREY';document.getElementById('stop').style='width:90px;color:LIGHTYELLOW;background-color:RED';</script>");
fclose($fr);
sleep(2);
}


}
fclose($fp);
//sleep(1);
ob_end_flush(); // <-- this trash will not work
flush();        // <--- if this garbage dont exist
sleep(5);// <-- but dont worry, a collector is here...

}
?>

Upvotes: 0

Ayush
Ayush

Reputation: 42450

From PHP's page on exec():

If a program is started with this function, in order for it to continue running in the background, the output of the program must be redirected to a file or another output stream. Failing to do so will cause PHP to hang until the execution of the program ends.

That means, unless you direct the output to a file, exec() is blocking and will pause execution of your PHP script until the command you issued exits.

You can redirect the output to a file, or if you don't care about the output, redirect it to /dev/null.

Finally, yet another alternate could be to fork a new PHP process and exec the command from there. You can fork a new PHP process using pcntl_fork.

Upvotes: 2

DevZer0
DevZer0

Reputation: 13535

for node try passing detached option

var spawn = require('child_process').spawn,
  proc = spawn('longCommand', ['&'], { detached: true } );

Node documentation on spawn

Upvotes: 1

Related Questions