Macで定期実行するlaunchdの使い方がハマってしまい、食わず嫌いをしていたが、ようやく原因がわかったので記事化。 私の場合、ハマったのはバッチファイルなどのプログラムの置き場所だった。 DocumentsやDownloadやDesktopなどは権限周りがうるさく、実行できなかったのが原因。 手順含めて記録しておく。
前提条件
- Mac M1(AppleSilicon)
ゴール
1分ごとにhellowworld.txtに実行日時とhelloworldを追記する
1.動かしたいプログラムを用意
プログラムは何でも良いが、今回はpythonで用意した。 プログラムは**「/Users/(ユーザー名)」**の直下に置く。 「Documents」や外部SSDなどの「/Volumes/〜」などではうまく動かなかった。
1from datetime import datetime2
3# 現在の日付と時刻を取得し、yymmddhhmmss形式にフォーマットする4current_time = datetime.now().strftime('%y-%m-%d %H:%M:%S')5
6# 書き出す内容を作成7text_to_write = f"{current_time} helloworld"8
9# ファイルに書き出し(ファイルパスを絶対パスにする)10with open("/Users/(ユーザー名)/helloworld.txt", "a") as file:11 file.write(text_to_write)
2.バッチファイルを用意する
anaconda3を使用しており、環境をアクティベイトしているが、必要なければ割愛してOK。 「python 絶対パス」で実行
1#!/bin/zsh2
3source /Users/(ユーザー名)/anaconda3/etc/profile.d/conda.sh4conda activate (仮想環境名)5python /Users/(ユーザー名)/helloworld.py
3.バッチファイルに実行権限を付与する
バッチファイルに実行権限を与える
1chmod +x /Users/(ユーザー名)/helloworld.sh
4.プロパティリスト(plist)を用意する
下記のサイトを参考にplistを用意する Launched - A Plist Generator
Webサービスで Mac OS X の launchd (plist) を作成してワンライナーでインストールする #plists - Qiita
1<?xml version="1.0" encoding="UTF-8"?>2<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">3<plist version="1.0">4 <dict>5 <key>Label</key>6 <string>com.example.helloworld</string>7
8 <!-- 1分ごとに実行 -->9 <key>StartInterval</key>10 <integer>60</integer>11
12 <!-- システム再起動後もタスクを起動 -->13 <key>RunAtLoad</key>14 <true/>15
15 collapsed lines
16 <!-- 実行するスクリプト -->17 <key>ProgramArguments</key>18 <array>19 <string>/Users/(ユーザー名)/helloworld.sh</string>20 </array>21
22 <!-- 標準出力(成功したときのログ) -->23 <key>StandardOutPath</key>24 <string>/Users/(ユーザー名)/helloworld_success.log</string>25
26 <!-- 標準エラー(失敗したときのログ) -->27 <key>StandardErrorPath</key>28 <string>/Users/(ユーザー名)/helloworld_error.log</string>29 </dict>30</plist>
5.プロパティリスト(plist)を「~/Library/LaunchAgents/」に移動、権限変更
1cp /Users/(ユーザー名)/com.example.helloworld.plist ~/Library/LaunchAgents/com.example.helloworld.plist2sudo chown root:wheel ~/Library/LaunchAgents/com.example.helloworld.plist3sudo chmod 644 ~/Library/LaunchAgents/com.example.helloworld.plist
6.プロパティリスト(plist)をロードし、定期実行を開始
1launchctl load ~/Library/LaunchAgents/com.example.helloworld.plist
7.プロパティリスト(plist)がロードされているか確認
1launchctl list | grep com.example.helloworld
8.プロパティリスト(plist)をアンロードし、定期実行を終了
1launchctl unload ~/Library/LaunchAgents/com.example.helloworld.plist
9.Launchdを強制実行
1launchctl start com.example.helloworld.plist
10.plistの構文エラー確認
1plutil start ~/Library/LaunchAgents/com.example.helloworld.plist
より詳細のエラー表示
1launchctl bootstrap system ~/Library/LaunchAgents/com.example.helloworld.plist