문제

쉘 스크립트를 호출해야하지만 출력에 대해 전혀 신경 쓰지 않는 PHP 스크립트가 있습니다. 쉘 스크립트는 여러 가지 비누 호출을 만들고 완료하는 데 속도가 느리므로 PHP 요청이 답장을 기다리는 동안 속도를 늦추고 싶지 않습니다. 실제로 PHP 요청은 쉘 프로세스를 종료하지 않고 종료 할 수 있어야합니다.

나는 다양한 것을 조사했다 exec(), shell_exec(), pcntl_fork(), 등. 기능이지만, 그들 중 누구도 내가 원하는 것을 정확히 제공하지 않는 것 같습니다. (또는 그들이 그렇게한다면, 나에게 어떻게 분명하지 않습니다.) 어떤 제안이 있습니까?

도움이 되었습니까?

해결책

"출력에 관심이 없다"는 경우 스크립트에 대한 실행을 호출 할 수 없었습니다. & 과정을 배경으로?

편집하다 - @ 통합Adamthehut 이 게시물에 댓글을 달면 전화에 추가 할 수 있습니다. exec:

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

그것은 둘 다 리디렉션됩니다 stdio (첫 번째 >) 그리고 stderr (2>) 에게 /dev/null 그리고 백그라운드에서 실행됩니다.

똑같은 일을하는 다른 방법이 있지만, 이것은 가장 간단합니다.


위의 이중 빨정에 대한 대안 :

" &> /dev/null &"

다른 팁

나는 사용했다 ~에 이를 위해 실제로 독립적 인 프로세스를 시작하고 있습니다.

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

모든 Windows 사용자에게 : 비동기 PHP 스크립트를 실행하는 좋은 방법을 찾았습니다 (실제로는 거의 모든 것과 함께 작동합니다).

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

원래 코드 : http://php.net/manual/en/function.exec.php#86329

Linux에서는 다음을 수행 할 수 있습니다.

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

이렇게하면 명령 프롬프트에서 명령을 실행 한 다음 PID를 반환하면> 0을 확인하여 작동하는지 확인할 수 있습니다.

이 질문은 비슷합니다. PHP에는 스레딩이 있습니까?

PHP-ECUTE-A-BACKGROURTE-PROCESS 좋은 제안이 있습니다. 나는 내 것이 꽤 좋다고 생각하지만 편견이 있습니다 :)

Linux에서는 명령이 끝날 때 암페어를 추가하여 새로운 독립 스레드에서 프로세스를 시작할 수 있습니다.

mycommand -someparam somevalue &

Windows에서 "시작"DOS 명령을 사용할 수 있습니다.

start mycommand -someparam somevalue

올바른 방법 (!)은

  1. 포크()
  2. setSid ()
  3. execve ()

Fork Forks, SetSid는 현재 프로세스에 마스터 1이 되라고 지시하고, Execte는 호출 프로세스를 호출 한 사람으로 대체하라고 지시합니다. 부모가 자녀에게 영향을 미치지 않고 종료 할 수 있도록.

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

 // parent's stuff
 exit();

나는 이것을 사용했다 ...

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

(어디 PHP_PATH 처럼 정의 된 콘트라스입니다 define('PHP_PATH', '/opt/bin/php5') 또는 이와 유사)

명령 줄을 통해 인수로 전달됩니다. PHP에서 읽으려면 참조하십시오 Argv.

내가 진정으로 나를 위해 일한 유일한 방법은 다음과 같습니다.

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

나는 또한 발견했다 Symfony 프로세스 구성 요소 이것에 유용합니다.

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

그것이 어떻게 작동하는지보십시오 Github Repo.

이름이 지정된 FIFO를 사용하십시오.

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

그런 다음 장기 실행 작업을 시작하려면 Newline을 작성하십시오 (트리거 파일에 차단되지 않음.

입력이보다 작다면 PIPE_BUF 그리고 그것은 싱글입니다 write() 작전, 당신은 FIFO에 논쟁을 쓸 수 있으며 $REPLY 대본에서.

PHP 스크립트를 다음과 같이 실행할 수도 있습니다 악마 또는 크론 조브: #!/usr/bin/php -q

큐를 사용하지 않으면 사용할 수 있습니다 proc_open() 이와 같이:

    $descriptorspec = array(
        0 => array("pipe", "r"),
        1 => array("pipe", "w"),
        2 => array("pipe", "w")    //here curaengine log all the info into stderror
    );
    $command = 'ping stackoverflow.com';
    $process = proc_open($command, $descriptorspec, $pipes);
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top