2013-07-30 56 views
0

我需要执行一个shell程序,该程序将运行一个相当长的进程,我不想等到该进程结束后才能继续执行我的PHP脚本。到目前为止,我想:使用PHP和节点异步运行shell命令

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”返回后。难道我做错了什么?

回答

1

从PHP的页面上exec()

如果程序开始使用此功能,以便它到 继续在后台运行,程序的输出必须是 重定向到一个文件或另一个输出流。如果不这样做, 会导致PHP挂起,直到程序执行结束。

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

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

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

+0

谢谢,这将是在分叉使用节点PHP进程的优势在哪里? – silkAdmin

+0

其中一个优点是,您的代码将更加独立,并且与安装了节点的系统无关。 – xbonez

1

node尝试通过detached选项

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

节点文档上spawn

0

尽管我在这里使用的文件名似乎很奇怪,为什么不试图看看我的原始代码的原型以下...我不能发布其他部分哥们,因为我已附加到它我的私人DB密码.. 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... 

} 
?>