php 有没有办法在不等待命令完成的情况下使用 shell_exec?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1019867/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 00:40:06  来源:igfitidea点击:

Is there a way to use shell_exec without waiting for the command to complete?

phpshell

提问by ToughPal

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 脚本,EG:

shell_exec('php measurePerformance.php 47 844 [email protected]');

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

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

回答by jitter

How about adding.

加起来怎么样。

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

shell_exec('php measurePerformance.php 47 844 [email protected] > /dev/null 2>/dev/null &');

Note this also gets rid of the stdio and stderr.

请注意,这也摆脱了 stdio 和 stderr。

回答by Brent Baisley

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 &");

回答by Oytun

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

回答by Oytun

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(我还将写入设置为拒绝)。

回答by CONvid19

Sure, for windowsyou 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 COMerror, add the extension to your php.iniand restart apache:

如果出现COM错误,请将扩展添加到您的php.ini并重新启动apache

[COM_DOT_NET]
extension=php_com_dotnet.dll

回答by CONvid19

Use PHP's popencommand, 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.

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

回答by Alfred

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。

回答by chaos

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.

如果它不在网页上,我建议生成某种信号(可能是将文件放入目录中),并让 cron 作业完成需要完成的工作。否则,我们很可能会进入使用pcntl_fork()exec()从 Apache 进程内部的领域,这就是糟糕的魔力。

回答by zacharydanger

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

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