使用PHP和节点异步运行shell命令

时间:2013-07-30 03:33:59

标签: php node.js

我需要执行一个shell程序,它将运行一个相当长的进程,我不想等到该进程结束,我的PHP脚本继续执行。到目前为止我试过了:

1:纯PHP

exec("longCommand &");

2:节点和php

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

节点:

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

console.log('return');

在这两种情况下,只有在“longCommand”返回后,脚本才会继续执行。我做错了吗?

3 个答案:

答案 0 :(得分:2)

来自exec()上的PHP页面:

  

如果程序是使用此功能启动的,则为了它   继续在后台运行,程序的输出必须是   重定向到文件或其他输出流。没有这样做会   导致PHP挂起,直到程序执行结束。

这意味着,除非您将输出定向到文件,否则exec()将被阻止并将暂停执行您的PHP脚本,直到您发出的命令退出。

您可以将输出重定向到文件,或者如果您不关心输出,请将其重定向到/dev/null

最后,另一个替代方案可能是从那里分叉一个新的PHP进程和exec命令。您可以使用pcntl_fork派生一个新的PHP进程。

答案 1 :(得分:1)

node尝试传递detached选项

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

spawn

上的节点文档

答案 2 :(得分:0)

虽然我在这里使用的文件名看起来很奇怪,为什么不试着看下面原始代码的工作原型...我不能发布其他部分dude,因为我附加了它我的私人数据库密码..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...

}
?>