0

我需要执行一个 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”返回后才会继续执行。难道我做错了什么?

4

3 回答 3

2

从 PHP 的页面exec()

如果使用此函数启动程序,为了使其继续在后台运行,程序的输出必须重定向到文件或另一个输出流。否则将导致 PHP 挂起,直到程序执行结束。

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

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

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

于 2013-07-30T03:39:58.510 回答
1

node尝试通过detached选项

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

spawn上的节点文档

于 2013-07-30T03:38:37.013 回答
0

虽然我在这里使用的文件名看起来很奇怪,但为什么不尝试查看下面的原始代码的工作原型......我无法发布其他部分,因为我已将我的私人数据库密码附加到它上面..eheheh


链接: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...

}
?>
于 2014-05-13T23:55:12.357 回答