是否有一种不用等待命令完成就可以使用shell_exec的方法?

时间:2022-08-27 21:33:51

I have a process intensive task that I would like to run in the background.

我有一个进程密集型的任务,我想在后台运行。

The user clicks on a page, the PHP script runs, and finally, based on some conditions, if required, then it has to run a shell script, E.G.:

用户点击一个页面,PHP脚本运行,最后,根据某些条件,如果需要,它必须运行shell脚本,例如:

shell_exec('php measurePerformance.php 47 844 email@yahoo.com');

Currently I use shell_exec, but this requires the script to wait for an output. Is there any way to execute the command I want without waiting for it to complete?

目前我使用shell_exec,但是这需要脚本等待输出。有什么方法可以在不等待它完成的情况下执行我想要的命令吗?

9 个解决方案

#1


123  

How about adding.

如何添加。

"> /dev/null 2>/dev/null &"

shell_exec('php measurePerformance.php 47 844 email@yahoo.com > /dev/null 2>/dev/null &');

Note this also gets rid of the stdio and stderr.

注意,这也去掉了stdio和stderr。

#2


18  

This will execute a command and disconnect from the running process. Of course, it can be any command you want. But for a test, you can create a php file with a sleep(20) command it.

这将执行一个命令,并断开与正在运行的进程的连接。当然,它可以是任何你想要的命令。但是对于测试,您可以使用sleep(20)命令创建一个php文件。

exec("nohup /usr/bin/php -f sleep.php > /dev/null 2>&1 &");

#3


11  

You can also give your output back to the client instantly and continue processing your PHP code afterwards.

您还可以立即将输出返回给客户端,然后继续处理PHP代码。

This is the method I am using for long-waiting Ajax calls which would not have any effect on client side:

这是我正在使用的方法,用于长时间等待的Ajax调用,它不会对客户端产生任何影响:

ob_end_clean();
ignore_user_abort();
ob_start();
header("Connection: close");
echo json_encode($out);
header("Content-Length: " . ob_get_length());
ob_end_flush();
flush();
// execute your command here. client will not wait for response, it already has one above.

You can find the detailed explanation here: http://oytun.co/response-now-process-later

您可以在这里找到详细的解释:http://oytun.co/response-now-process-later

#4


8  

On Windows 2003, to call another script without waiting, I used this:

在Windows 2003上,无需等待就可以调用另一个脚本,我使用了以下方法:

$commandString = "start /b c:\\php\\php.EXE C:\\Inetpub\\wwwroot\\mysite.com\\phpforktest.php --passmsg=$testmsg"; 
pclose(popen($commandString, 'r'));

This only works AFTER giving changing permissions on cmd.exe - add Read and Execute for IUSR_YOURMACHINE (I also set write to Deny).

这只在对cmd授予更改权限后才有效。exe -为IUSR_YOURMACHINE添加Read和Execute(我还设置write to Deny)。

#5


5  

Use PHP's popen command, e.g.:

使用PHP的popen命令,例如:

pclose(popen("start c:\wamp\bin\php.exe c:\wamp\www\script.php","r"));

This will create a child process and the script will excute in the background without waiting for output.

这将创建一个子进程,脚本将在后台执行,而不需要等待输出。

#6


2  

That will work but you will have to be careful not to overload your server because it will create a new process every time you call this function which will run in background. If only one concurrent call at the same time then this workaround will do the job.

这将会起作用,但你必须小心不要让你的服务器超载,因为它会在每次调用这个函数时创建一个新的进程。如果同时只有一个并发调用,那么这个变通方法就可以完成这项工作。

If not then I would advice to run a message queue like for instance beanstalkd/gearman/amazon sqs.

如果没有,我建议运行一个消息队列,例如beanstalkd/gearman/amazon sqs。

#7


1  

If it's off of a web page, I recommend generating a signal of some kind (dropping a file in a directory, perhaps) and having a cron job pick up the work that needs to be done. Otherwise, we're likely to get into the territory of using pcntl_fork() and exec() from inside an Apache process, and that's just bad mojo.

如果它不在web页面上,我建议生成某种信号(可能在目录中删除文件),并让cron作业接收需要完成的工作。否则,我们可能会在Apache进程中使用pcntl_fork()和exec(),这是一种糟糕的魔咒。

#8


1  

For windows you can use:

对于windows,你可以使用:

$WshShell = new COM("WScript.Shell");
$oExec = $WshShell->Run("C:/path/to/php-win.exe -f C:/path/to/script.php", 0, false);

Note:

注意:

If you get a COM error, add the extension to your php.ini and restart apache:

如果出现COM错误,请将扩展添加到php中。ini和重新启动apache:

[COM_DOT_NET]
extension=php_com_dotnet.dll

#9


-2  

You could always post over some AJAX to a page that calls the shell_exec().

您总是可以通过一些AJAX发布到调用shell_exec()的页面。

#1


123  

How about adding.

如何添加。

"> /dev/null 2>/dev/null &"

shell_exec('php measurePerformance.php 47 844 email@yahoo.com > /dev/null 2>/dev/null &');

Note this also gets rid of the stdio and stderr.

注意,这也去掉了stdio和stderr。

#2


18  

This will execute a command and disconnect from the running process. Of course, it can be any command you want. But for a test, you can create a php file with a sleep(20) command it.

这将执行一个命令,并断开与正在运行的进程的连接。当然,它可以是任何你想要的命令。但是对于测试,您可以使用sleep(20)命令创建一个php文件。

exec("nohup /usr/bin/php -f sleep.php > /dev/null 2>&1 &");

#3


11  

You can also give your output back to the client instantly and continue processing your PHP code afterwards.

您还可以立即将输出返回给客户端,然后继续处理PHP代码。

This is the method I am using for long-waiting Ajax calls which would not have any effect on client side:

这是我正在使用的方法,用于长时间等待的Ajax调用,它不会对客户端产生任何影响:

ob_end_clean();
ignore_user_abort();
ob_start();
header("Connection: close");
echo json_encode($out);
header("Content-Length: " . ob_get_length());
ob_end_flush();
flush();
// execute your command here. client will not wait for response, it already has one above.

You can find the detailed explanation here: http://oytun.co/response-now-process-later

您可以在这里找到详细的解释:http://oytun.co/response-now-process-later

#4


8  

On Windows 2003, to call another script without waiting, I used this:

在Windows 2003上,无需等待就可以调用另一个脚本,我使用了以下方法:

$commandString = "start /b c:\\php\\php.EXE C:\\Inetpub\\wwwroot\\mysite.com\\phpforktest.php --passmsg=$testmsg"; 
pclose(popen($commandString, 'r'));

This only works AFTER giving changing permissions on cmd.exe - add Read and Execute for IUSR_YOURMACHINE (I also set write to Deny).

这只在对cmd授予更改权限后才有效。exe -为IUSR_YOURMACHINE添加Read和Execute(我还设置write to Deny)。

#5


5  

Use PHP's popen command, e.g.:

使用PHP的popen命令,例如:

pclose(popen("start c:\wamp\bin\php.exe c:\wamp\www\script.php","r"));

This will create a child process and the script will excute in the background without waiting for output.

这将创建一个子进程,脚本将在后台执行,而不需要等待输出。

#6


2  

That will work but you will have to be careful not to overload your server because it will create a new process every time you call this function which will run in background. If only one concurrent call at the same time then this workaround will do the job.

这将会起作用,但你必须小心不要让你的服务器超载,因为它会在每次调用这个函数时创建一个新的进程。如果同时只有一个并发调用,那么这个变通方法就可以完成这项工作。

If not then I would advice to run a message queue like for instance beanstalkd/gearman/amazon sqs.

如果没有,我建议运行一个消息队列,例如beanstalkd/gearman/amazon sqs。

#7


1  

If it's off of a web page, I recommend generating a signal of some kind (dropping a file in a directory, perhaps) and having a cron job pick up the work that needs to be done. Otherwise, we're likely to get into the territory of using pcntl_fork() and exec() from inside an Apache process, and that's just bad mojo.

如果它不在web页面上,我建议生成某种信号(可能在目录中删除文件),并让cron作业接收需要完成的工作。否则,我们可能会在Apache进程中使用pcntl_fork()和exec(),这是一种糟糕的魔咒。

#8


1  

For windows you can use:

对于windows,你可以使用:

$WshShell = new COM("WScript.Shell");
$oExec = $WshShell->Run("C:/path/to/php-win.exe -f C:/path/to/script.php", 0, false);

Note:

注意:

If you get a COM error, add the extension to your php.ini and restart apache:

如果出现COM错误,请将扩展添加到php中。ini和重新启动apache:

[COM_DOT_NET]
extension=php_com_dotnet.dll

#9


-2  

You could always post over some AJAX to a page that calls the shell_exec().

您总是可以通过一些AJAX发布到调用shell_exec()的页面。