foldrr's weblog

旧ブログ http://d.hatena.ne.jp/foldrr/

PHP の exec(), shell_exec(), system()

どれを使えばいいのか

exec() を使えばいい。
shell_exec() はリターンコードが取得不能なので不便。
system() はリダイレクトしないと勝手に標準出力へ出力するので不便。

まとめ

関数名 第1引数 第2引数 第3引数 戻値 出力
exec コマンド stdout リターンコード stdout なし
shell_exec コマンド - - stdout なし
system コマンド リターンコード - stdout あり

exec() 第2引数 stdout の注意点

exec() の標準出力は第2引数 stdout へ追加されるので注意。
つまり、連続して exec() を呼び出す場合は第2引数に渡す変数を毎回クリアする必要がある。

非同期実行

exec, shell_exec, system どれでも可能。
以下は exec での例。

exec('filename > /dev/null &');

ポイントは標準出力をリダイレクトする点。
リダイレクトしないと & を付けていても処理がブロックされてしまう。

id:DQNEOさんより頂いたコメント元に追記。
上記方法ではfilenameの処理が中断されてしまう場合がある。
これはlogrotateがログをローテートするタイミングで、対象のプロセスを終了させるため。
なぜプロセスを終了させるのかというと、
ローテートした後、プロセスが最新のログファイルへ書き込みできるようにするため。
デーモンの場合はそれでいいのだが、
上記のように単発でプログラムを実行する場合はプロセスを終了されては困る。
そのため下記が正しい。

exec('nohup filename > /dev/null &');

バックティック演算子

shell_exec と同じ。