こんにちは、ライフハックブロガーのたぬ(@tanuhack)です!
「作ったPythonのプログラムが、ある決まった時間に自動で実行されればなあ…」
Macのcron(クーロン)という機能を使えば可能です!!
[aside]補足cronとは、UNIX系のOS(MacやLinuxなど)に入っているプログラムの1つです。
プログラムを起動する時間を予め設定しておくことで、cronが自動で定期的にプログラムを実行してくれるようになります。
例えば、毎分実行させたり、一日おきにに実行させたり、毎週月曜の8時に実行させたりと、好きな間隔で設定することが出来ます。
[/aside]プログラムの定時実行は主に以下の3つの用途で使われることが多いです。
- スクレイピングやデータ収集、様々な自動操作をするため
- プログラムが正しく動作しているか確認するため
- ログをとったりバックアップをしたりするため
私は、①の理由でcronをよく使っています\(^o^)/
jupyter notebookやターミナルから手動でプログラムを実行させていた時期があったなんて、今では信じられないくらい定時実行は便利です。抜け出せる自信がありません!!
さあ、あなたもcronを習得して、人間が行うには下らない単純作業を自動化させ、人生のクオリティを上げていきましょう!!
それでは、どうぞ。
cronはMacにしかありません。そのため当記事は、Macユーザー向けの内容となっております。悪しからず。
「どうしても、Windowsでやりたいんだ」という方は、『Python タスクスケジューラ』と検索してみて下さい。
目次
cronの使い方
ターミナルでcrontab -e
と実行すると、cronの登録画面(vim)が出てきます。

この黒い画面にcronのコマンドを登録していきます。
vimの操作する
この黒い画面はvim(ヴィム)と言って、普通のエディタのようなGUI(マウスや指などで操作できる画面のこと)操作ではなく、CUI(キーボードでしか操作できない画面)操作でしか動きません。
最初は戸惑うかもしれませんが、慣れればどうってことありませんよ\(^o^)/
vimには2つのモードがあります。
- インサート(挿入)モード:文字が入力できる
- コマンドモード:文字が入力できない
vimを起動したら、コマンドモードが起動します。キーボードのIを押すと、コマンドモードからインサートモードに切り替わり、文字を入力することが出来るようになります。

今回cronを作成する例として、デスクトップ(/Users/Kenta(※あなたのユーザー名)/Desktop/)にあるhello-cron.py
というPythonファイルを毎朝9:00に定時実行させるcronを作ってみましょう。
# hello-cron.py(Pythonのバージョンを出力するプログラム)
import sys
print('Python:' + sys.version)
プログラムの実行タイミングを設定する
cronは、次のような書式で実行する『タイミング』と『コマンド』を設定します。
分 時 日 月 曜日 コマンド
* * * * * some_command
分 | 0〜59 |
---|---|
時 | 0〜23 |
日 | 1〜31 |
月 | 1〜12 |
曜日 | 0〜7(0,7=日曜、1=月曜、2=火曜、3=水曜、4=木曜、5=金曜、6=土曜) |
0 21 * * * 毎日21:00分に実行
0 18 * * 2 毎週火曜の18:00に実行
0,10 18 * * 1-5 毎平日の18:00と18:10に実行
0,10,20,30,40,50 * * * * 毎日10分毎に実行
*/10 * * * * 毎日10分毎に実行
0 9 1 * * 毎月1日の9:00に実行
* * * * * 毎分実行
ゆえに『デスクトップ(/Users/Kenta(※あなたのユーザー名)/Desktop/)にあるHello-cron.py
というPythonファイルを毎朝9時に定時実行させるcron』は以下のように設定できます。
vimを閉じる
vimをインサートモードからコマンドモードに切り替えるためにはescキーを押します。
そして『:wq』と入力して、returnキーでcronを保存します。
うまく保存できれば、ターミナルに『installing new crontab』と表示されます。
出力を確認する
Pythonのprint()
メソッドは、ターミナル上に標準出力されません。
では、実際にどうやって出力を確認するのかというと、ターミナル上でmail
コマンドを使って確認します。
とは言ったものの、mail
コマンドで毎回確認するのは不便すぎるので、『標準出力』と『エラーメッセージ』を一緒に『logファイル』として出力する方法を紹介します。
先程のcronを登録する際に、コードを付け足します。
cron自体は正しく動作しています。
しかし、Python3を実行したはずが、なぜかPython2.7系になっていますね。
実は、cronでPythonプログラムをユーザーが意図した通りに動かすためには、次に紹介する4つのポイントを押さえなくてはいけません。
注意すべき4つのポイント
- Python3のPATHを通す
- 相対パスではなく絶対パスを記述する
- 環境変数は注意が必要
- 文字コードを設定する
それぞれ見ていきましょう。
Python3のPATHを通す
先程、Python3を実行したつもりがPython2.7系で実行されていましたね。おそらく、私以外にも多くの方が2.7系で実行されると思います。
[aside]補足Macには標準でPython2.7系がインストールされている(※2019年1月現在)[/aside]
そのため、ターミナル上ではPython3(python --version
コマンドでバージョンを確認)が動いていても、cron上ではPython2.7系が動いてしまいます。
Python 3.6.6 :: Anaconda custom (64-bit)
結論から言うと、crontabでPython3が動くようにPATHを通してあげればOKです。
ターミナルでecho $PATH
と入力して、そのPATHをcrontabに貼り付けます。
/anaconda3/bin:/Library/Frameworks/Python.framework/Versions/3.6/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Applications/VMware Fusion.app/Contents/Public:/opt/X11/bin:/Users/kenta/.nodebrew/current/bin:/Users/Kenta/.nodebrew/current/bin
PATHを通してあげると、ちゃんとcronで実行したプログラムでもPython3系を動かすことが出来ました。
相対パスではなく絶対パスを記述する
cronで実行するプログラムでは、相対パスは使えません。すべて絶対パスに書き換えましょう!
環境変数は注意が必要
先程のPATHみたいに、cronの環境変数はターミナルのそれと全然違うことが分かりますね。
一応確認してみると、、、
SHELL=/bin/sh
USER=Kenta
PATH=/usr/bin:/bin
PWD=/Users/Kenta
SHLVL=1
HOME=/Users/Kenta
LOGNAME=Kenta
_=/usr/bin/env
うわ、すくなっ…。ご覧の通り、全然用意されていません。
プログラムの中で環境変数を使用している場合は、『プログラムをそのまま変えずにcrontab上で環境変数を定義する』か『(※流出したら危ないけど)プログラムで環境変数を使わず、変数にKEYやPASSを直接代入する』か、で代用してください。
文字コードを設定する
出力に日本語を含む場合、次のようなエラーが発生します。
cronにLANG=ja_JP.UTF-8
と記述しておけばPythonプログラムに日本語が含まれても大丈夫です。
print('プログラムに日本語が含まれても大丈夫!')
さいごに
今回は、Pythonを定時実行させるために欠かせないcronの使い方と注意すべき4つのポイントを紹介しました。
crontab -e
でcrontabを起動PATH=あなたのパス
LANG=ja_JP.UTF-8
あなたはどんな目的でcronを使いますか?
- スクレイピングやデータ収集、様々な自動操作をするため
- プログラムが正しく動作しているか確認するため
- ログをとったりバックアップをしたりするため
cronで良い自動化ライフを!