【Mac標準搭載】cronの使い方・よくあるエラーの解決方法まで解説

Macでプログラムを決まった時間に自動で実行させたいけど

いい方法ないかなーって方へ

Macに標準搭載されているcronを使うと

好きな時間に指定したプログラムファイルを自動で

実行することができます

今回は競馬データ自動取得を

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が起動している状態でないと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がフルディスクアクセスに

表示されていますが、初めての場合は表示されていません

フルディスクアクセス:Mac上のすべてのアプリにアクセスできる権限のこと

cronでは、他のプログラムファイルを勝手に実行するため

そのファイルにアクセスする権限を与えておく必要があります

これで初期設定の部分は終了です

次にcronの設定方法を説明します


cronの使い方

cronを起動するにはターミナルで以下のコマンドを実行します

コマンドを実行するディレクトリはどこでも大丈夫です

$ crontab -e

実行するとcronの設定画面に変わります

『-e』の他にもオプションがあるので紹介しておきます

  • -u: ユーザーを指定(指定したユーザーで自動実行される)
  • -l: 設定しているcronの一覧を表示する
  • -r: 設定中のcronを全て削除する
  • -e: cronを設定するエディタを起動する
↑crontab画面

設定画面はvimと呼ばれるエディターモードになっています

vimはいろんな機能を搭載していますが

今回の記事では説明は割愛します

おへんじ
vimの最低限のコマンドは説明するから分からくても大丈夫だよ

ここに起動したい日時と実行したいファイルを記載します

次に書き方の法則を解説していきます

次の画像を参考にしてみてください

これで月、日、時、分の指定した時間に

指定したファイルを自動で実行してくれます

ファイル名はフルパスで指定する必要があります

sample.pyファイル場所が『usr/work/sample.py』の場合は
そのままパスも含めて記載する必要があります

次にcron設定の具体例を見ていきましょう

設定文の中に 『*』を使用していますが、

例えば、『分』を指定する箇所に『*』を指定すると

毎分という意味になります

具体的な数値を入力しない場合は『*』と入力します

時を指定する箇所に『*/1』を入力すると1時間おきに実行されます

分の場合は1分おきに実行されます

例4の場合、時の箇所に『2-4,8』と入力していますが

/これは『-』(ハイフン)を使用すれば

その間の時間が指定できます

『,』(カンマ)を使用して区切ると

複数の時間を指定することができます

こんな感じで指定したい時間と

実行したいプログラムをフルパスで書きます

実際の操作方法は下の動画を参考にしてみてください

おへんじ
文書でも手順を書いておくね
  1. ターミナル起動
  2. 『crontab -e』コマンドでcronの設定画面(vim)を開く
  3. 『i』でINSERTモードに入る(文字が入力できる)
  4. cronの設定を書く
  5. EscボタンでINSERTモードを抜ける
  6. 『: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
1       ・・・標準出力
2      ・・・標準エラー出力
2>&1・・・標準エラー出力を標準出力と同じ場所に出力する
1>&2・・・標準出力を標準エラー出力と同じ場所に出力する
>> ・・・ログを追記
>   ・・・ログを上書き

sample.shに記載している『2>&1』は

標準出力(1)と標準エラー出力(2)を

cron.logファイルに書き出すことを示しています

2>&1を書いてない場合は標準出力のみ指定されることになります(例を1>&2にするとログファイルに出力できない)

ログへの出力についてよくわからない方は

下の記事でわかりやすく解説されている方が

おられましたのでそちらを参考に・・・

Qiita

はじめに初心者の頃によく混乱した Bash の「標準エラー出力を標準出力に流す」記法 2>&1 についてで…

やることを図にすると・・・

sample.shの内容は・・・

  1. hello.pyを実行する
  2.  実行ログは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 – -』→読み込み
『r』・・・読み込み
『w』・・・書き込み
『x』・・・実行

所有者にだけ実行の権限を与えます

権限を変更するコマンドは・・・

chmod 744 sample.sh

このコマンドで所有者に実行権限が付与されます

おへんじ
『744』の箇所を『777』にするとすべてのユーザーに読み・書き・実行の権限が
付与されるよ(『774』は所有者・所有グループに全ての権限付与)

今回の記事では『chmod』コマンドの解説は省略しますので

気になる方は、こちらの記事を参考にしてみてください

Qiita

#簡易早見#形式chmod 権限設定 ファイルパス#chmod 744 test.txt4 2 1r w x#概要chm…

再度、権限の確認をしてみます

$ 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を使用して

競馬結果の取得を

自動化する方法を紹介していきます


最新情報をチェックしよう!