【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を実行していたら相当の量になるので、そこは運用でログを無視するか、定期的にログを整理してやるということになっているのだろう。

Laravel, php

Posted by 異世界攻略班