PHP 中的异步 shell exec

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/222414/
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-24 21:58:27  来源:igfitidea点击:

Asynchronous shell exec in PHP

phpasynchronousshell

提问by AdamTheHutt

I've got a PHP script that needs to invoke a shell script but doesn't care at all about the output. The shell script makes a number of SOAP calls and is slow to complete, so I don't want to slow down the PHP request while it waits for a reply. In fact, the PHP request should be able to exit without terminating the shell process.

我有一个 PHP 脚本,它需要调用一个 shell 脚本,但根本不关心输出。shell 脚本进行了许多 SOAP 调用并且完成速度很慢,所以我不想在等待回复时减慢 PHP 请求的速度。实际上,PHP 请求应该能够在不终止 shell 进程的情况下退出。

I've looked into the various exec(), shell_exec(), pcntl_fork(), etc. functions, but none of them seem to offer exactly what I want. (Or, if they do, it's not clear to me how.) Any suggestions?

我研究了各种exec(), shell_exec(),pcntl_fork()等功能,但似乎没有一个能提供我想要的功能。(或者,如果他们这样做,我不清楚如何。)有什么建议吗?

回答by warren

If it "doesn't care about the output", couldn't the exec to the script be called with the &to background the process?

如果它“不关心输出”,那么不能用&后台进程调用脚本的 exec吗?

EDIT- incorporating what @AdamTheHutcommented to this post, you can add this to a call to exec:

编辑- 结合@AdamTheHut对这篇文章的评论,您可以将其添加到以下调用中exec

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

That will redirect both stdio(first >) and stderr(2>) to /dev/nulland run in the background.

这会将stdio(first >) 和stderr( 2>)重定向到/dev/null并在后台运行。

There are other ways to do the same thing, but this is the simplest to read.

还有其他方法可以做同样的事情,但这是最容易阅读的。



An alternative to the above double-redirect:

上述双重重定向的替代方案:

" &> /dev/null &"

回答by Czimi

I used atfor this, as it is really starting an independent process.

我为此使用了at,因为它实际上是在启动一个独立的过程。

<?php
    `echo "the command"|at now`;
?>

回答by LucaM

To all Windows users: I found a good way to run an asynchronous PHP script (actually it works with almost everything).

致所有 Windows 用户:我找到了一种运行异步 PHP 脚本的好方法(实际上它几乎适用于所有东西)。

It's based on popen() and pclose() commands. And works well both on Windows and Unix.

它基于 popen() 和 pclose() 命令。并且在 Windows 和 Unix 上都运行良好。

function execInBackground($cmd) {
    if (substr(php_uname(), 0, 7) == "Windows"){
        pclose(popen("start /B ". $cmd, "r")); 
    }
    else {
        exec($cmd . " > /dev/null &");  
    }
} 

Original code from: http://php.net/manual/en/function.exec.php#86329

原始代码来自:http: //php.net/manual/en/function.exec.php#86329

回答by Darryl Hein

On linux you can do the following:

在 linux 上,您可以执行以下操作:

$cmd = 'nohup nice -n 10 php -f php/file.php > log/file.log & printf "%u" $!';
$pid = shell_exec($cmd);

This will execute the command at the command prompty and then just return the PID, which you can check for > 0 to ensure it worked.

这将在命令提示符处执行命令,然后只返回 PID,您可以检查其 > 0 以确保它工作。

This question is similar: Does PHP have threading?

这个问题类似:PHP有线程吗?

回答by Mark Biek

php-execute-a-background-processhas some good suggestions. I think mine is pretty good, but I'm biased :)

php-execute-a-background-process有一些很好的建议。我觉得我的还不错,但我有偏见:)

回答by Leo

In Linux, you can start a process in a new independent thread by appending an ampersand at the end of the command

在 Linux 中,您可以通过在命令末尾附加一个&符号来在新的独立线程中启动进程

mycommand -someparam somevalue &

In Windows, you can use the "start" DOS command

在 Windows 中,您可以使用“启动”DOS 命令

start mycommand -someparam somevalue

回答by Leo

the right way(!) to do it is to

正确的方法(!)

  1. fork()
  2. setsid()
  3. execve()
  1. 叉子()
  2. setid()
  3. 执行()

fork forks, setsid tell the current process to become a master one (no parent), execve tell the calling process to be replaced by the called one. so that the parent can quit without affecting the child.

fork forks,setsid 告诉当前进程成为主进程(没有父进程),execve 告诉调用进程被被调用进程替换。这样父母可以退出而不影响孩子。

 $pid=pcntl_fork();
 if($pid==0)
 {
   posix_setsid();
   pcntl_exec($cmd,$args,$_ENV);
   // child becomes the standalone detached process
 }

 // parent's stuff
 exit();

回答by philfreo

I used this...

我用过这个...

/** 
 * Asynchronously execute/include a PHP file. Does not record the output of the file anywhere.  
 * Relies on the PHP_PATH config constant.
 *
 * @param string $filename  file to execute
 * @param string $options   (optional) arguments to pass to file via the command line
 */ 
function asyncInclude($filename, $options = '') {
    exec(PHP_PATH . " -f {$filename} {$options} >> /dev/null &");
}

(where PHP_PATHis a const defined like define('PHP_PATH', '/opt/bin/php5')or similar)

(其中PHP_PATH定义为类似define('PHP_PATH', '/opt/bin/php5')或类似的常量)

It passes in arguments via the command line. To read them in PHP, see argv.

它通过命令行传递参数。要在 PHP 中阅读它们,请参阅argv

回答by Gordon Forsythe

The only way that I found that truly worked for me was:

我发现真正对我有用的唯一方法是:

shell_exec('./myscript.php | at now & disown')

回答by Anton Pelykh

I also found Symfony Process Componentuseful for this.

我还发现Symfony Process Component对此很有用。

use Symfony\Component\Process\Process;

$process = new Process('ls -lsa');
// ... run process in background
$process->start();

// ... do other things

// ... if you need to wait
$process->wait();

// ... do things after the process has finished

See how it works in its GitHub repo.

在其GitHub 存储库中查看它是如何工作的。