Posted at

PHPスクリプトをシェルのバックグラウンド実行で動かす方法

More than 3 years have passed since last update.


はじめに

シェルコマンドでは、各コマンドを&でつなぐことでバックグラウンド実行を行うことが出来ます。

これを使って複数のコマンドの同時実行などが可能です。

便利ですよね。

ただ、この方法でphpのスクリプトをバックグラウンド実行しようとしても出来ずにハマったのでその解決法をメモ。


バックグラウンド起動成功例

sleep 10を2回起動しているにもかかわらず、totalの実行時間は10秒で済んでいる


~% date;echo 'Start jobs!'; sleep 10 & sleep 10 & wait;date

Thu Jan 8 12:58:40 JST 2015

Start jobs!

[5] 27000

[6] 27001

[5] done sleep 10

[6] done sleep 10

Thu Jan 8 12:58:50 JST 2015


ただし、PHPで記載されたスクリプトなど、一部のコマンドに関してはバックグラウンド実行を行うことが出来ません。


バックグラウンド起動をしていない場合は成功する


~% php -r 'echo "hoge\n";'

~% hoge



バックグラウンド起動をさせようとした場合は標準入出力が失敗し、以下のエラーがでてsuspendする


~% php -r 'echo "hoge\n";' &

~% [5] + suspended (tty output) php -r 'echo "hoge\n";'



解決法1 < /dev/nullをつける

とりあえず手元で簡単に行ないたい場合はこちらのやり方で大丈夫なようです。

一番簡単な例


~% php -r 'echo "hoge\n";' < /dev/null&

[7] 27068

~% hoge

[7] done php -r 'echo "hoge\n";' < /dev/null


複数同時起動させる例1

→成功


~% php -r 'echo "hoge\n";' < /dev/null& php -r 'echo "fuga\n";' < /dev/null&;

[7] 27119

[8] 27120

~% hoge

fuga

[8] done php -r 'echo "fuga\n";' < /dev/null

~%

[7] done php -r 'echo "hoge\n";' < /dev/null


複数同時起動させる例2

→成功 各PHPスクリプトにsleep(10)を入れているにもかかわらず、全体で10秒で完了している


~% date; php -r 'sleep (10); echo "hoge\n";' < /dev/null& php -r 'sleep (10); echo "fuga\n";' < /dev/null&; wait; date;

Thu Jan 8 13:22:22 JST 2015

[7] 27124

[8] 27125

fuga

hoge

[8] done php -r 'sleep (10); echo "fuga\n";' < /dev/null

[7] done php -r 'sleep (10); echo "hoge\n";' < /dev/null

Thu Jan 8 13:22:32 JST 2015



解決法2 シェルスクリプトファイルを記載してそちらを実行する

上記のワンライナーを以下のシェルスクリプトに書き換えます。

おすすめはこちらです。

この時、< /dev/nullは不要です。


BGSample.sh

#!/bin/sh

date;
php -r 'sleep(10); echo "fuga\n";' &
php -r 'sleep(10); echo "hoge\n";' &
wait;
date;

実行結果


~% sh ./BGSample.sh

Thu Jan 8 13:26:30 JST 2015

fuga

hoge

Thu Jan 8 13:26:40 JST 2015


こちらも大丈夫でした。実行時間が10秒ですので、各phpのスクリプトが並列で実行されていることがわかりますし、出力もわかりやすいですね。