web-dev-qa-db-ja.com

コマンドの完了を待たずにShell_execを使用する方法はありますか?

バックグラウンドで実行したいプロセス集中タスクがあります。

ユーザーがページをクリックすると、PHPスクリプトが実行され、最後に、必要に応じていくつかの条件に基づいて、シェルスクリプトを実行する必要があります。

Shell_exec('php measurePerformance.php 47 844 [email protected]');

現在、 Shell_execbutを使用していますが、これにはスクリプトが出力を待つ必要があります。私が望むコマンドを実行する方法はありますかなしでコマンドの完了を待っていますか?

87
ToughPal

追加してください。

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

Shell_exec('php measurePerformance.php 47 844 [email protected] > /dev/null 2>/dev/null &');

これは、stdioとstderrも削除することに注意してください。

140
jitter

これにより、コマンドが実行され、実行中のプロセスから切断されます。もちろん、任意のコマンドを使用できます。しかし、テストのために、sleep(20)コマンドでphpファイルを作成できます。

exec("Nohup /usr/bin/php -f sleep.php > /dev/null 2>&1 &");
26
Brent Baisley

また、出力を即座にクライアントに返し、後で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

11
Oytun

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の読み取りと実行を追加します(書き込みも拒否に設定します)。

8
user275759

PHPのpopenコマンドを使用します。例:

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

これにより、子プロセスが作成され、スクリプトは出力を待たずにバックグラウンドで実行されます。

6
BI Architect

もちろん、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
6
Pedro Lobito

これは機能しますが、バックグラウンドで実行されるこの関数を呼び出すたびに新しいプロセスが作成されるため、サーバーをオーバーロードしないように注意する必要があります。同時に1つの同時呼び出しのみの場合、この回避策はジョブを実行します。

そうでない場合は、beanstalkd/gearman/Amazon sqsなどのメッセージキューを実行することをお勧めします。

1
Alfred

Webページから外れている場合は、何らかの種類の信号を生成し(ディレクトリにファイルをドロップするなど)、cronジョブに必要な作業を取得させることをお勧めします。そうでなければ、Apacheプロセス内からpcntl_fork()exec()を使用する領域に入る可能性が高く、それはただの悪いことです。

1
chaos