Macでプログラムを決まった時間に自動で実行させたいけど
いい方法ないかなーって方へ
Macに標準搭載されているcronを使うと
好きな時間に指定したプログラムファイルを自動で
実行することができます
今回は競馬データ自動取得を
cronで実現するための前段の記事になります
この記事を読むとわかること・・
- cronの使い方(設定方法、権限の設定、ログの出力について)
- シェルスクリプトの書き方の超基礎
開発環境
解説をする前に私が使用している環境を書いておきます
- MacBook Pro : (13-inch, 2020, Four Thunderbolt 3 ports)
- プロセッサ:2 GHz クアッドコアIntel Core i5
- メモリ:16GB
- python version:3.9.5
cronでできること
使い方の解説の前に超ざっくりcronで
できることを説明しておきます
cronで実現できることはざっくりこんな感じです・・・
- 任意の時間に指定したプログラムファイルを自動で実行してくれる
- シェルスクリプトやpythonファイル、phpファイルなどいろんなファイルが自動実行できる
- Macでcronは標準で使用できるためインストール作業等は不要
- 設定がシンプルで簡単
(スリープ状態、シャットダウン状態では自動実行はできない)
指定した時刻にMacをスリープ状態から
起動状態にできる設定もあります
Macの『システム環境設定>バッテリー>スケジュール』
から設定できるので確認してみてください
cronの代替候補
cronのようにプログラムを自動実行できる候補として
Launchdが挙げられます
どちらもプログラムの自動実行ができます
またMacではLaunchdを使用することが推奨されています
私の場合、どちらも使ってみましたが
cronの方が設定がシンプルで簡単に扱えたので
cronを使用しています
cronを使う前の事前設定
次にcronを使う前に事前にしておく
設定があるので説明します
それはフルディスクアクセスにcronを追加しておくことです
手順については、以下の動画を参考に設定してみてください
フルディスクアクセスにcronを追記するときに
pathでcronを探す場合は、
『shift+command+g』を同時に押すと
pathの入力画面が表示されます
『/usr/sbin/cron』と入力すると
cronが表示されるので『開く』
をクリックして追加します
動画では、追加する前にcronがフルディスクアクセスに
表示されていますが、初めての場合は表示されていません
cronでは、他のプログラムファイルを勝手に実行するため
そのファイルにアクセスする権限を与えておく必要があります
これで初期設定の部分は終了です
次にcronの設定方法を説明します
cronの使い方
cronを起動するにはターミナルで以下のコマンドを実行します
コマンドを実行するディレクトリはどこでも大丈夫です
$ crontab -e
実行するとcronの設定画面に変わります
『-e』の他にもオプションがあるので紹介しておきます
- -u: ユーザーを指定(指定したユーザーで自動実行される)
- -l: 設定しているcronの一覧を表示する
- -r: 設定中のcronを全て削除する
- -e: cronを設定するエディタを起動する
設定画面はvimと呼ばれるエディターモードになっています
vimはいろんな機能を搭載していますが
今回の記事では説明は割愛します
ここに起動したい日時と実行したいファイルを記載します
次に書き方の法則を解説していきます
次の画像を参考にしてみてください
これで月、日、時、分の指定した時間に
指定したファイルを自動で実行してくれます
sample.pyファイル場所が『usr/work/sample.py』の場合は
そのままパスも含めて記載する必要があります
次にcron設定の具体例を見ていきましょう
設定文の中に 『*』を使用していますが、
例えば、『分』を指定する箇所に『*』を指定すると
毎分という意味になります
具体的な数値を入力しない場合は『*』と入力します
時を指定する箇所に『*/1』を入力すると1時間おきに実行されます
分の場合は1分おきに実行されます
例4の場合、時の箇所に『2-4,8』と入力していますが
/これは『-』(ハイフン)を使用すれば
その間の時間が指定できます
『,』(カンマ)を使用して区切ると
複数の時間を指定することができます
こんな感じで指定したい時間と
実行したいプログラムをフルパスで書きます
実際の操作方法は下の動画を参考にしてみてください
- ターミナル起動
- 『crontab -e』コマンドでcronの設定画面(vim)を開く
- 『i』でINSERTモードに入る(文字が入力できる)
- cronの設定を書く
- EscボタンでINSERTモードを抜ける
- 『:wq』(保存して閉じる)と入力してcron設定画面を保存して終了する(ターミナル画面へ戻る)
これでcronを使用した一連の流れは理解できたと思います
権限の設定について
cronの設定方法が理解できたところで
次は私が実際につまづいてしまった権限の変更について
説明をしておきます
少し上の方でフルディスクアクセスの設定を
説明しましたが
それに加えて次の設定を
しておく必要があります
具体例を使って解説していきます
次のようなファイルを用意します
フォルダ構成
$ tree.
(実行結果)
sample_dir
├── cron.log
├── hello.py
└── sample.sh
cron.log
# ここにログが出力されるように設定する
hello.py
# coding: UTF-8
print("hello") # helloと出力されるだけ
sample.sh
#!/bin/bash
/Users/username/.pyenv/shims/python3 /Users/username/sample_dir/hello.py >> /Users/username/sample_dir/cron.log 2>&1
2 ・・・標準エラー出力
2>&1・・・標準エラー出力を標準出力と同じ場所に出力する
1>&2・・・標準出力を標準エラー出力と同じ場所に出力する
>> ・・・ログを追記
> ・・・ログを上書き
sample.shに記載している『2>&1』は
標準出力(1)と標準エラー出力(2)を
cron.logファイルに書き出すことを示しています
ログへの出力についてよくわからない方は
下の記事でわかりやすく解説されている方が
おられましたのでそちらを参考に・・・
やることを図にすると・・・
sample.shの内容は・・・
- hello.pyを実行する
- 実行ログはcron.logファイルに出力する
よってsample.shを実行すると
hello.pyが実行されてcron.logに
『hello』と出力されるはずです
cronの設定は毎日12時00分に
sample.shを実行するように設定してみます
00 12 * * * /Users/username/sample_dir/sample.sh
これでうまくいくはずだったんですが・・・
12時になってもcron.logにログ出力されませんでした
どうやらcronで実行するファイルの権限を変更しないと
アクセス拒否で実行できない場合がある
ってことがわかりました
cronによるログは標準では『/var/mail/username』に出力されます
『/var/mail/username』をみてみると・・・
From username@usernamenoMacBook-Pro.local Thu Dec 8 22:12:01 2022
Return-Path: <username@usernamenoMacBook-Pro.local>
(略)
/bin/sh: /Users/username/sample_dir/sample.sh: Permission denied
いろいろログが出力されていますが
最後の文に『Permission deined』(アクセス拒否)
と記載されています
やはり権限がなくてアクセスが拒否されたっぽいです
現在の権限を確認してみます
$ ls -l # 各ファイル・ディレクトリの権限を確認できるコマンド
(実行結果)
-rw-r--r-- (略) cron.log
-rw-r--r-- (略) hello.py
-rw-r--r-- (略) sample.sh
sample.shの現在の権限設定は・・・
- 所 有 者 『r w -』→読み込み・書き込み
- 所有グループ『r – -』→読み込み
- そ の 他 『r – -』→読み込み
『w』・・・書き込み
『x』・・・実行
所有者にだけ実行の権限を与えます
権限を変更するコマンドは・・・
chmod 744 sample.sh
このコマンドで所有者に実行権限が付与されます
付与されるよ(『774』は所有者・所有グループに全ての権限付与)
今回の記事では『chmod』コマンドの解説は省略しますので
気になる方は、こちらの記事を参考にしてみてください
再度、権限の確認をしてみます
$ ls -l # 各ファイル・ディレクトリの権限を確認できるコマンド
(実行結果)
-rw-r--r-- (略) cron.log
-rw-r--r-- (略) hello.py
-rwxr--r-- (略) sample.sh
sample.shの所有者権限の部分が『rw-』→『rwx』となっています
これで実行権限の設定ができましたので
再度実行してみると
cron.log
hello
これで予定どおりcronを使用してシェルスクリプトを実行して
指定したファイルにログを出力することができました
次回の記事では、cronを使用して
競馬結果の取得を
自動化する方法を紹介していきます