Asynchronous shell exec in PHP

前端 未结 13 1985

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,

相关标签:
13条回答
  • 2020-11-22 01:14

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

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

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

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

    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 &"
    
    0 讨论(0)
  • 2020-11-22 01:15

    the right way(!) to do it is to

    1. fork()
    2. setsid()
    3. execve()

    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.

     $pid=pcntl_fork();
     if($pid==0)
     {
       posix_setsid();
       pcntl_exec($cmd,$args,$_ENV);
       // child becomes the standalone detached process
     }
    
     // parent's stuff
     exit();
    
    0 讨论(0)
  • 2020-11-22 01:16

    Use a named fifo.

    #!/bin/sh
    mkfifo trigger
    while true; do
        read < trigger
        long_running_task
    done
    

    Then whenever you want to start the long running task, simply write a newline (nonblocking to the trigger file.

    As long as your input is smaller than PIPE_BUF and it's a single write() operation, you can write arguments into the fifo and have them show up as $REPLY in the script.

    0 讨论(0)
  • 2020-11-22 01:19

    You can also run the PHP script as daemon or cronjob: #!/usr/bin/php -q

    0 讨论(0)
  • 2020-11-22 01:23

    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_PATH is a const defined like define('PHP_PATH', '/opt/bin/php5') or similar)

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

    0 讨论(0)
  • 2020-11-22 01:30

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

    It's based on popen() and pclose() commands. And works well both on Windows and 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

    0 讨论(0)
提交回复
热议问题