「初心者向け」cronを用いたプログラム定期実行の注意点

2020.02.26

こんにちは。最近、はじめてcronを使用した下地です。

cronとは「利用者の設定したスケジュールに従って指定されたプログラムを定期的に起動してくれるもの」です。

シェルスクリプトをスケジュールした時間で定期実行するために使用したのですが、設定についてハマったのでその内容についてまとめたいと思います。

検証内容

検証に用いたファイル構成は以下のようになっております。

pythonファイル(example.py)を処理するためのシェルスクリプト(example.sh)を作成し、そのシェルスクリプトをcronで定期実行出来るような構成になっております。

example.pyはlogのパスを受け取り、ファイルが存在するかの確認をするものです。

import sys
import os

def main():
    args = sys.argv
    if os.path.exists(args[1]):
        print("exists")
    else:
        print("not exists")

if __name__ == '__main__':
    main()

example.shは下記のようになっておりpython実行時にlogのパスを渡し、結果をtestディレクトリに出力します。example直下にてbash example.sh実行すると、testディレクトリ直下にfile.txtが生成されました。

python example.py log/example.log | tee test/file.txt

次はcronです。 下記のようにcrontabで設定しました。しかし、時間になってもファイルは生成されません。失敗してるらしいですが、エラーの表示がないため原因をどう追っていいかわかりませんでした。

00 12 * * * bash /Users/example/python/test.sh

原因

結論として、cronでexample.shを実行する際に、example.pyファイルへのパスを指定する必要がありました。example.shにてexample.pyへのフルパスを使用するか、実行ディレクトを移動するかの2つの方法があります。今回は実行ディレクトリを移動するコマンドを追加する事で、crontabで指定した時間にファイルの生成を行うことが出来ました。

example.sh

cd example
python example.py log/example.log | tee test/file.txt

また、crontabへの設定時に以下のように > /tmp/test.txt 2>&1を記述することで任意の場所にログを保存することができます。

00 12 * * * bash /Users/example/python/test.sh > /tmp/test.txt 2>&1

今回のエラー内容については下記のようになっており、ファイルが無いよと怒られてました。

can't open file 'example.py': [Errno 2] No such file or directory

まとめ

cronに慣れておらず基本的な内容ですがハマりました。cronの実行時は通常使用しているイメージと異なるので注意が必要です。 もっと複雑なハマりポイントがあるかもしれませんが、/tmp/test.txt 2>&1のようにログを出力させれば、その内容を確認することでデバッグがスムーズになると思います。私と同じようにシェルスクリプトだと上手くいったけどcronの設定でハマった方の助けになれば幸いです。

参考リンク