【PHP/Laravel】スケジューラの実行について
アプリケーションの App\Console\Kernel クラスのscheduleで定義したメソッドを実行していく。
標準では、サーバーに次を追加するとある。
* * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1
次のように分割する。
- " ***** "
- " cd /path-to-your-project && php artisan schedule:run "
- " >> /dev/null 2>&1 "
ワイルドカードは左から第一フィールドとして第五まで。それぞれ、
- 第1フィールド:分(0〜59)
- 第2フィールド:時(0〜23)
- 第3フィールド:日(1〜31)
- 第4フィールド:月(1〜12)
- 第5フィールド:曜日(0〜6、0が日曜日)
となっている。例えば、毎月28日の12時半に実行させるなら、" 30 12 28 * * "となるが、実際に実行時期はscheduleメソッドで定義している。
cd /path-to-your-project && php artisan schedule:run は、指定したpath-to-your-projectまで問題無く移動できたら、Laravelのスケジューラを実行する。
スケジューラを実行する際の条件が、" >> /dev/null 2>&1 "。
" >> "はリダイレクト演算子を表しており、実行結果をファイル名 /dev/null に書き込む。指定したファイルに書き込まれるが、/dev/null は(標準出力の)ログやエラーメッセージを無効化するので、ここでの出力が無視される。
リダイレクト演算子の1と2はそれぞれ次の意味になる。
- 1: 標準出力
- 2: 標準エラー出力
- ちなみに0は標準入力
なので、2>&1は標準エラー出力を、標準出力と同ファイルに表示することを意味する。この2>&1は、2>1になると標準エラー出力をファイル名「1」にリダイレクトさせるという意味になり、想定通り動かない。
&アンパサンドの意味については、シェルスクリプト(Bash)の記号の意味 の記事のリンクにあるが、やはり繋ぎの意味(and)で、これがあることで1がリダイレクト演算子と判断できる。
" >> "と " > "にはどのような違いがあるのか。単純に言うと、>> は追記で、 > は上書きとなる。例えば、指定のファイルに既に" Hello "と書かれていて、それを
echo "Hello, World!" >> file.txt
とすると、>> は" Hello "が二つ書き込まれていることになる。
" >> /dev/null " はスケジューラの実行結果を/dev/nullに追記する。これが > なら上書きされる。だが、/dev/null は出力を捨てる。
さて、/dev/null 2>&1 ではなく、2>&1 /dev/null ならどうなるか。
>> の後にはファイル名がくるので、2>&1がファイル名と解されて、スケジューラの実行結果は無視されず、2>&1というファイルに書き込まれることになり、/dev/nullは意味を為さなくなる。>> と >はどちらもファイルが存在しなければ、新規で作成されるので、2>&1のファイルが作成され、想定通りの結果にはならない。
なので、
* * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1
は、「ワイルドカードで示した日時で、ファイル移動後にスケジューラを実行するが、その実行結果(標準エラー出力を標準出力と同じ場所に表示されるが)は無視する」という意味になり、単にスケジューラを実行するということになる。
しかし、いい加減覚えよう。 `command > /dev/null 2>&1`の意味 の記事でも触れられているが、そもそもログを無視するのはどうなのか。
/dev/null は不要な出力(文字通り不要なログやログファイルで圧迫される)を制御するために使用される。確かに、デイリーでcronを実行していたら相当の量になるので、そこは運用でログを無視するか、定期的にログを整理してやるということになっているのだろう。