사용자 조치에 따라 디렉토리 사본을 실행해야하지만 디렉토리가 상당히 크기 때문에 사용자가 사본을 완료하는 데 걸리는 시간을 인식하지 않고 그러한 조치를 수행 할 수 있기를 원합니다.
어떤 제안이라도 대단히 감사하겠습니다.
답변
이것이 Linux 컴퓨터에서 실행되고 있다고 가정하면 항상 다음과 같이 처리했습니다.
exec(sprintf("%s > %s 2>&1 & echo $! >> %s", $cmd, $outputfile, $pidfile));
명령을 실행하고 명령 $cmd
출력을로 리디렉션 $outputfile
하고 프로세스 ID를에 기록합니다 $pidfile
.
이를 통해 프로세스가 수행중인 작업과 여전히 실행 중인지를 쉽게 모니터링 할 수 있습니다.
function isRunning($pid){
try{
$result = shell_exec(sprintf("ps %d", $pid));
if( count(preg_split("/\n/", $result)) > 2){
return true;
}
}catch(Exception $e){}
return false;
}
답변
프로세스를 편리한 언어 (php / bash / perl / etc)로 서버 측 스크립트로 작성한 다음 PHP 스크립트의 프로세스 제어 기능에서 호출하십시오.
이 함수는 표준 io가 출력 스트림으로 사용되는지 여부를 감지하고 그렇다면 해당 반환 값을 설정합니다.
proc_close( proc_open( "./command --foo=1 &", array(), $foo ) );
“sleep 25s”를 명령으로 사용하여 명령 줄에서이를 빠르게 테스트했으며 매력처럼 작동했습니다.
( 답변은 여기에 있습니다 )
답변
이것을 명령에 추가하려고 할 수 있습니다
>/dev/null 2>/dev/null &
예.
shell_exec('service named reload >/dev/null 2>/dev/null &');
답변
Windows 에서이 기능을 테스트하기위한 매우 간단한 예를 추가하고 싶습니다.
다음 두 파일을 작성하여 웹 디렉토리에 저장하십시오.
foreground.php :
<?php
ini_set("display_errors",1);
error_reporting(E_ALL);
echo "<pre>loading page</pre>";
function run_background_process()
{
file_put_contents("testprocesses.php","foreground start time = " . time() . "\n");
echo "<pre> foreground start time = " . time() . "</pre>";
// output from the command must be redirected to a file or another output stream
// http://ca.php.net/manual/en/function.exec.php
exec("php background.php > testoutput.php 2>&1 & echo $!", $output);
echo "<pre> foreground end time = " . time() . "</pre>";
file_put_contents("testprocesses.php","foreground end time = " . time() . "\n", FILE_APPEND);
return $output;
}
echo "<pre>calling run_background_process</pre>";
$output = run_background_process();
echo "<pre>output = "; print_r($output); echo "</pre>";
echo "<pre>end of page</pre>";
?>
background.php :
<?
file_put_contents("testprocesses.php","background start time = " . time() . "\n", FILE_APPEND);
sleep(10);
file_put_contents("testprocesses.php","background end time = " . time() . "\n", FILE_APPEND);
?>
위 파일을 작성한 디렉토리에 쓸 수있는 권한을 IUSR에 부여하십시오.
읽기 및 실행 C : \ Windows \ System32 \ cmd.exe에 IUSR 권한 부여
웹 브라우저에서 foreground.php를 누르십시오
출력 배열의 현재 타임 스탬프 및 로컬 리소스 번호를 사용하여 브라우저에 다음을 렌더링해야합니다.
loading page
calling run_background_process
foreground start time = 1266003600
foreground end time = 1266003600
output = Array
(
[0] => 15010
)
end of page
위의 파일이 저장된 동일한 디렉토리에 testoutput.php가 표시되고 비어 있어야합니다.
위의 파일이 저장된 디렉토리와 동일한 디렉토리에 testprocesses.php가 표시되고 현재 타임 스탬프가 포함 된 다음 텍스트가 포함되어야합니다.
foreground start time = 1266003600
foreground end time = 1266003600
background start time = 1266003600
background end time = 1266003610
답변
PHP 페이지가 완료되기를 기다리지 않고 백그라운드에서 무언가를 수행해야하는 경우 wget 명령으로 “호출 된”다른 (백그라운드) PHP 스크립트를 사용할 수 있습니다. 이 배경 PHP 스크립트는 물론 시스템의 다른 PHP 스크립트와 마찬가지로 권한으로 실행됩니다.
다음은 gnuwin32 패키지의 wget을 사용하는 Windows의 예입니다.
훌륭한 배경 코드 (파일 test-proc-bg.php) …
sleep(5); // some delay
file_put_contents('test.txt', date('Y-m-d/H:i:s.u')); // writes time in a file
포 그라운드 스크립트, 하나는 호출 …
$proc_command = "wget.exe http://localhost/test-proc-bg.php -q -O - -b";
$proc = popen($proc_command, "r");
pclose($proc);
이 기능이 제대로 작동하려면 popen / pclose를 사용해야합니다.
wget 옵션 :
-q keeps wget quiet.
-O - outputs to stdout.
-b works on background
답변
다음은 PHP에서 백그라운드 프로세스를 시작하는 함수입니다. 마지막으로 다른 접근 방식과 매개 변수를 많이 읽고 테스트 한 후에 실제로 Windows에서도 작동하는 것을 만들었습니다.
function LaunchBackgroundProcess($command){
// Run command Asynchroniously (in a separate thread)
if(PHP_OS=='WINNT' || PHP_OS=='WIN32' || PHP_OS=='Windows'){
// Windows
$command = 'start "" '. $command;
} else {
// Linux/UNIX
$command = $command .' /dev/null &';
}
$handle = popen($command, 'r');
if($handle!==false){
pclose($handle);
return true;
} else {
return false;
}
}
참고 1 : Windows에서는 /B
다른 곳에서 제안한대로 매개 변수를 사용하지 마십시오 . 프로세스가 start
명령 자체 와 동일한 콘솔 창을 실행하도록 하여 프로세스가 동 기적으로 처리되도록합니다. 별도의 스레드에서 프로세스를 비동기식으로 실행하려면을 사용하지 마십시오 /B
.
참고 2 : start ""
명령이 인용 된 경로 인 경우 뒤에 빈 큰 따옴표 가 필요합니다. start
명령은 처음 인용 된 매개 변수를 창 제목으로 해석합니다.
답변
글쎄, 나는 조금 더 빠르고 사용하기 쉬운 버전을 발견했다.
shell_exec('screen -dmS $name_of_screen $command');
작동합니다.
