문제
쉘 스크립트를 호출해야하지만 출력에 대해 전혀 신경 쓰지 않는 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 &");
}
}
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
올바른 방법 (!)은
- 포크()
- setSid ()
- 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);