AWSでcronからpythonが実行できない。
cronで実行したときだけ no module
エラーが発生する。
このような状況に陥る原因と対策を紹介。
ImportError: No module named 'hoge'
AWSのEC2インスタンス上でcrontabを設定して、pythonコードを自動実行しようとすると
ImportError: No module named 'hoge'
が発生する場合がある。
要はモジュールがインストールされておらず、実行時に見つけられなくてエラーになった時のメッセージだ。
回避方法としてはモジュールを pip install hoge
でインストールしてしまう事だ。
しかしインストール済みなのにcronから実行したときだけエラーになる場合がある。
そのような場合は sudo pip install hoge
で解決するかもしれない。
ただし sudo
で解決してしまうと根本原因を見逃してしまう。
根本原因
sudo pip install hoge
で解決するということは、ssh接続時とcron実行時で利用しているPython環境が異なるという事だ。
cron時は別のPython環境を参照しているので、ssh接続時のPython環境ではインストールしてあったモジュールが見つからずに ImportError: No module named 'hoge'
となってしまうのである。
pyenv等でPython環境を分けているとこの問題が発生する。
またAMIなどで別のEC2インスタンスを元にしてEC2インスタンスを作った場合もこの問題に気付きにくい。
確認方法
コマンドライン上やcron上で
python --version > version.txt
を実行してバージョンが違えば、Python環境が2つあることが確認できる。
解決方法
真の解決方法はcronのPython環境とssh接続時のPython環境を合わせる事。
Python環境を合わせるには env
コマンドで表示された PATH=...
の部分をcrontabの最初に記述するとcron実行時でもPATHが読み込まれて、SSH接続時と同じPythonが実行される。
[code lang=text]
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin
* * * * * cronjob
[/code]
まとめ
AWSでcronからpythonが実行できず、no module
エラーが発生する場合はcron時とssh接続時で異なるPythonを使っていることが原因。
crontabにPATHを記述することでcron時とssh接続時のPython環境を合わせることができる。