명령이 완료 될 때까지 기다리지 않고 shell_exec를 사용하는 방법이 있습니까?


95

백그라운드에서 실행하고 싶은 프로세스 집약적 인 작업이 있습니다.

사용자가 페이지를 클릭하면 PHP 스크립트가 실행되고 마지막으로 필요한 경우 일부 조건에 따라 쉘 스크립트 EG를 실행해야합니다.

shell_exec('php measurePerformance.php 47 844 email@yahoo.com');

현재 내가 사용 shell_exec , 하지만 출력을 기다리려면 스크립트가 필요합니다. 완료 때까지 기다리지 않고 원하는 명령을 실행할 수있는 방법이 있습니까?


참고 : 프로세스는 즉시 시작해야하므로 cron은 옵션이 아닙니다.
ToughPal 2009-06-19

2
참고 사항 : 모든 사람 (검색 엔진 / 사기 사용자)이 페이지에 액세스 할 수 없는지 확인하고 공유 환경에있는 경우 모든 스크립트 (특히 PHP!)의 실행 시간이 제한 될 수 있습니다. 어쨌든 set_time_limit / php.ini를 살펴볼 수 있습니다.
merkuro

답변:


150

추가하는 것은 어떻습니까.

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

shell_exec('php measurePerformance.php 47 844 email@yahoo.com > /dev/null 2>/dev/null &');

이것은 또한 stdio 및 stderr를 제거합니다.


2
아니요. 부작용이 없습니다. 프로세스의 stdio 또는 stderr 출력을 원할 경우 stackoverflow.com/questions/45953/…을
jitter

1
질문 : 그것은 출력을 버리는 것입니다. PHP는 실행을 계속하기 전에 프로세스가 끝날 때까지 기다리거나 실행 후 잊어 버리나요?
Alan Storm

5
예는 버립니다. 예 발사하고 잊어 버리
jitter

3
참고 : > /dev/null 2>&1 &다른 답변에서 볼 수 있듯이 > /dev/null 2>/dev/null &여기에 간결한 형식이 있습니다. 이것은 기본적으로 "STDERR (2)를 STDOUT (& 1)과 같은 위치로 리디렉션"하는 것입니다.
rymo

3
나는 보통 echo $를 추가하여 스크립트를 실행하는 PID를 얻습니다! >> /tmp/pid.txt는 exec 명령 끝에 있지만 출력 및 오류를 / dev / null로 리디렉션하면 더 이상 pid 파일이 없습니다. 출력을 기다리지 않고 exec에 의해 시작된 스크립트의 PID를 얻을 수 있습니까?
hugsbrugs

28

이렇게하면 명령이 실행되고 실행중인 프로세스에서 연결이 끊어집니다. 물론 원하는 모든 명령이 될 수 있습니다. 그러나 테스트를 위해 sleep (20) 명령으로 PHP 파일을 만들 수 있습니다.

exec("nohup /usr/bin/php -f sleep.php > /dev/null 2>&1 &");

이것이 더 낫습니까 아니면 shell_exec입니까?
realtebo 2015

안녕하세요,이 shell_exec ( "nohup / usr / bin / php -f example.com/notifications/sendnotifications_async > / dev / null 2> & 1 &");
Waseem Bashir

모두 nohup&?
bugmenot123

11

또한 출력을 즉시 클라이언트에 다시 제공하고 나중에 PHP 코드를 계속 처리 할 수 ​​있습니다.

이것은 클라이언트 측에 영향을 미치지 않는 Ajax 호출을 오랫동안 기다리는 데 사용하는 방법입니다.

ob_end_clean();
ignore_user_abort();
ob_start();
header("Connection: close");
echo json_encode($out);
header("Content-Length: " . ob_get_length());
ob_end_flush();
flush();
// execute your command here. client will not wait for response, it already has one above.

자세한 설명은 http://oytun.co/response-now-process-later 에서 찾을 수 있습니다.


1
작전 ... 여기서 좀비 질문을 깨우고 있었는데 깨닫지 못했습니다. 그러나이 정보는 다른 사람들에게 도움이 될 수 있습니다.
Oytun

3
이것은이없는 것도 shell_exec 함께 할 수있는
bugmenot123

8

Windows 2003에서 기다리지 않고 다른 스크립트를 호출하기 위해 다음을 사용했습니다.

$commandString = "start /b c:\\php\\php.EXE C:\\Inetpub\\wwwroot\\mysite.com\\phpforktest.php --passmsg=$testmsg"; 
pclose(popen($commandString, 'r'));

이것은 변경 권한을 부여한 후에 만 ​​작동합니다 cmd.exe-읽기 및 실행을 추가하십시오 IUSR_YOURMACHINE(쓰기도 거부로 설정했습니다).


7

물론 windows다음을 사용할 수 있습니다.

$WshShell = new COM("WScript.Shell");
$oExec = $WshShell->Run("C:/path/to/php-win.exe -f C:/path/to/script.php", 0, false);

노트 :

당신이 얻을 경우 COM오류를, 당신에 확장자를 추가 php.ini하고 다시 시작 apache:

[COM_DOT_NET]
extension=php_com_dotnet.dll

나는 잘 모르겠지만 그것은 나를 위해 일했습니다. 누구든지 wscript.shell이 ​​무엇이며 무엇을하는지 설명하십시오.
GeekWithGlasses

이 줄이 출력을 제공하지 않는 이유를 설명해 주시겠습니까? `$ oExec = $ WshShell-> Run ( 'C : \ Users \ Shreyash \ Desktop \ phantomjs-2.1.1-windows \ bin \ phantomjs.exe -f C : \ xampp \ htdocs \ composer \ test_0.js', 0 , false);`
GeekWithGlasses

test_0.js에 오류가있을 수 있습니다. 팬텀 로그를 확인하십시오.
CONvid19

6

PHP의 popen명령을 사용하십시오 . 예 :

pclose(popen("start c:\wamp\bin\php.exe c:\wamp\www\script.php","r"));

그러면 자식 프로세스가 생성되고 스크립트는 출력을 기다리지 않고 백그라운드에서 실행됩니다.


4
자식 프로세스가 끝날 때까지 기다립니다. 최소한 승리
Max Chernopolsky

여기서 배경 화는 실행하려는 exe를 접두사로 지정하는 Windows "시작"명령의 도움으로 이루어지며, 생략하면 작동하지 않으며 다른 OS에서 작동 할 것으로 예상하지 않습니다.하지만 작동합니다. 나를 위해 작동합니다, 감사합니다! :-)
Antony

1

웹 페이지에서 벗어난 경우 일종의 신호를 생성하고 (아마도 디렉토리에 파일을 드롭) cron 작업이 수행해야 할 작업을 선택하도록하는 것이 좋습니다. 그렇지 않으면, 우리는 사용의 영토에 들어갈 가능성이 pcntl_fork()exec()아파치 프로세스 내부에서, 그리고 그건 그냥 나쁜 모조입니다.


1
당신은 나쁜 모조라고 말했습니다. 자세히 설명해 주시겠습니까?
Mayank

1

작동하지만 백그라운드에서 실행되는이 함수를 호출 할 때마다 새 프로세스를 생성하므로 서버에 과부하가 걸리지 않도록주의해야합니다. 동시에 하나의 동시 호출 만 있으면이 해결 방법이 작업을 수행합니다.

그렇지 않다면 예를 들어 beanstalkd / gearman / amazon sqs와 같은 메시지 대기열을 실행하는 것이 좋습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.