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


95

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

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

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

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


注:プロセスはすぐに開始する必要があるため、cronはオプションではありません。
ToughPal 2009年

2
簡単なメモ:誰もがページにアクセスできないようにしてください(検索エンジン/詐欺ユーザー)。また、共有環境を使用している場合、すべてのスクリプト(特にphp!)の実行時間はおそらく制限されます。いずれの場合でも、set_time_limit / php.iniを確認してください。
merkuro、2009年

回答:


149

追加はどうですか。

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

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

これはstdioとstderrも取り除くことに注意してください。


2
いいえ、副作用はありません。あなたがいつか決めた場合、あなたはstdioのか、あなたのプロセスの標準エラー出力を検討したいstackoverflow.com/questions/45953/...
ジッタ

1
質問:それは出力を破棄するだけですよね?PHPは、実行を続行する前にプロセスが完了するまで待機しますか、それとも起動して忘れますか?
アランストーム

5
はい、破棄します。はい火を忘れて
ジッタ

3
注:> /dev/null 2>&1 &他の回答で見られるように、> /dev/null 2>/dev/null &ここに示したのは簡潔な形式です。これは基本的に「STDERR(2)をSTDOUT(&1)と同じ場所にリダイレクトする」と言っています。
rymo 2015

3
通常、echo $!を追加して、実行中のスクリプトのPIDを取得します。>> execコマンドの最後に/tmp/pid.txtがありますが、出力とエラーを/ dev / nullにリダイレクトすることにより、これ以上pidファイルはありません。
hugsbrugs 2016

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 2017

なぜ両方 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
Ops ...私はここでゾンビの質問を起こしていた、私は気づかなかった。しかし、この少しの情報は他の人にとって有益かもしれません。
オイトゥン2013年

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 2017

この行が何も出力しない理由を説明していただけますか?`$ 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 2017

test_0.jsにエラーがある可能性があります。ファントムログを確認してください。
CONvid19

6

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

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

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


4
子プロセスの終了を待ちます。少なくともWinでは
Max Chernopolsky、2016

ここでのバックグラウンド化は、実行したいexeにプレフィックスを付けるWindowsの「start」コマンドの助けを借りて達成されます。省略した場合は機能しません。また、別のOSで機能するとは思わないでしょう...私のために働く、ありがとう!:-)
アントニー

1

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


1
あなたはそれが悪いモジョだと言った。詳しく説明してもらえますか?
Mayank 2017

1

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

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.