php でシェル呼び出しをバックグラウンドにするには
シェル経由のコマンド実行をバックグラウンド(プロセスの親 にする)には次のとおりに書く。
<?php shell_exec ( "sleep 100 > /dev/null 2>/dev/null & ");
STDOUT/STDERRをphp から切り離せば、プロセスをバックグラウンド・ジョブにすることが出来る。
複数行ならどうするのか
コマンド1行に対して1つの &
が必要なので、複数行呼び出すときは複数回 &
をすると大変なことになる。
これはひどい結果になる。
この場合、次々とコマンドを呼び出だすだけになる。
<?php shell_exec ( "sleep 100 > /dev/null 2>/dev/null & "); shell_exec ( "sleep 100 > /dev/null 2>/dev/null & "); shell_exec ( "sleep 100 > /dev/null 2>/dev/null & "); shell_exec ( "sleep 100 > /dev/null 2>/dev/null & ");
このコマンドが、一時ファイルを作って作業して一時ファイルを消すような処理をしていると、処理中の一時ファイルが先に消されちゃったりする。
複数行に渡るコマンドを実行するには
コマンドを { $cmd }
のように 括弧で区切る方法が一番楽
<?php shell_exec ( "{sleep 100;sleep 100;sleep 100;sleep 100;} > /dev/null 2>/dev/null & ");
これは、気づくのに時間がかかった。シェル呼び出しは 括弧{}
でくくってあげると一括りのコマンドとして実行できるんですね
shell_exec で 2&1>/dev/null &
をつけると、が sh -c 経由になるので もしやと思ったらビンゴだった。
カッコつきのコマンドのエラーを探すには
括弧をつけると、シェルスクリプトのエラーを探すのが面倒になる。エラーが出た時に追いかけるのが面倒です。
この場合は、エラーと標準出力の書き出し先を明示してあげれば楽ちんになった。
<?php shell_exec ( "sleep 100 > /tmp/stdout 2>/tmp/stderr & ");
phpの shell_exec 関数は 標準出入力がファイルに流されてて、&がついてたら apache プロセスから切り離すようになるみたいです。
関連資料
2018-03-04
バックグラウンドでroot は書きすぎなので削るなど