Table of Contents
1 はじめに
PythonのスクリプトをLinuxマシン上で定期実行することを考えます。Linuxにはジョブスケジューラーのcronがありますが、必要ライブラリをpipでインストール済みのvenv環境を使うには少し工夫が必要です。
2 venv環境を使う
venv環境をactivateしてPythonスクリプトを実行するためには、cronから
python <script>.py
のように直接Pythonを呼んでスクリプトを実行するのではなく、ヘルパーのシェルスクリプトに頼ります。
しかし、venv環境をactivateするsourceコマンドは普通のshにはなく、bashを使わなくてはいけません。そこで、例えば次のようなスクリプトを作ります。
#!/usr/bin/bash cd </path/to/venv/folder> source bin/activate bin/python <python_script>.py
よく目にする #!/bin/sh
でなくbashを指定することと、 </path/to/venv/folder>/bin/python
を使うところがポイントです。
これをrun_script.sh としてセーブし、実行可能にします。
chmod a+x run_script.sh
3 crontabに登録する
crontabに登録してcron実行するために、
sudo crontab -e
を実行します。すると、viでcrontabが開かれるので、
0 */4 * * * </path/to/venv/folder>/run_script.sh
のような行を追加します。上記は4時間毎の実行です。 0
は(毎時)ゼロ分を、 */4
は4時間毎を意味します。
左端の5個のフィールドは以下のフォーマットになっています。
* * * * * | | | | +--- 曜日(0-6; 日曜が0) | | | +----- 月(1-12) | | +------- 日(1-31) | +--------- 時(0-23) +----------- 分(0-59)
きちんと登録されたかどうかは以下のコマンドで表示、確認できます。
sudo crontab -l
デバッグのためには、もっと頻繁に、例えば2分に1回の実行とし、print文やエラーをファイルに出力させるといいと思います。
*/2 * * * * </path/to/venv/folder>/run_script.sh >> /tmp/out.txt 2>&1
上記において、 2>&1
の部分は、エラーを標準出力にリダイレクトしています。
実際にこれが実行されたかどうかはログを見ます。
sudo tail -f /var/log/cron
次の実行が出力されたら、/tmp/out.txtを見に行きます。
- そもそも/tmp/out.txtが作成されているか
- out.txtにエラーが出ていないか
といったことを見ます。2回目以降は、実行される前に/tmp/out.txtを消しておくと、切り分けが少し楽になります。
4 終わりに
上記のテクニックを使って、オフィスのラボにあるサーバーがダウンしていないかを自動で定期的に確認し、ダウンしていたらSlackにメッセージをポストするようにしました。更に、サーバーにインストール済みのバージョンよりも新しいバージョンが無いか、Jenkinsをチェックして比較しています。
このように、社内システムのAPIを使って「退屈なこと(boring stuff)」を自動化するのに、手軽に使えて高機能なPythonは向いていると思います。