我需要执行一个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”返回后,脚本才会继续执行。我做错了吗?
答案 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 } );
上的节点文档
答案 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...
}
?>