目次
launchd
macOSのサービス管理ツール。initやcronの代替となる。
欠点はplistというmacのあちこちで使われているxmlの可読性が最悪であること。正直JSONかYAMLにしてほしいと皆が思っている。
※ 本来plistはxcodeなどのツールで編集する前提のフォーマットである。可能ならxcodeを使うことをお勧めする(そのxcodeのplistエディタも使いにくいのだが・・・)
定期実行ジョブの例
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>moe.nullpon.cron.test</string> <key>StartCalendarInterval</key> <dict> <key>Weekday</key> <integer>0</integer> <key>Hour</key> <integer>23</integer> <key>Minute</key> <integer>45</integer> </dict> <key>WorkingDirectory</key> <string>/Users/nullpon/apps</string> <key>Program</key> <string>/Users/nullpon/apps/cron.sh</string> <key>StandardOutPath</key> <string>/Users/hisanori/apps/cron.out</string> <key>StandardErrorPath</key> <string>/Users/hisanori/apps/cron.err</string> </dict> </plist>
パラメータ
詳細は plist(5) を参照
Label
このジョブの識別子。必須。
launchdがジョブの識別に使うので一意でなければならない。ベンダー間での重複を避けるため com.apple.hogehoge
のような逆ドメイン名を使う事が多い
StartCalendarInterval
定期実行用の設定。指定の日時に起動する設定。Weekdayは0 - 6を指定。0が日曜、6が土曜日に対応
arrayでductを並べる事で複数日時を設定可能
KeepAlive
アプリを常駐させる。サーバアプリケーションやバックグラウンドで起動し続けるサービス用の設定。以前はOnDemandという項目で制御していたがMac OS X 10.5からKeepAliveに変わった
RunAtLoad
ジョブが登録されたら即起動する。KeepAliveとともに使用される
WorkingDirectory
このジョブを起動した時のカレントディレクトリ
Program / ProgramArguments
コマンドへのパス。引数などがある場合はProgramArgumentsを使う
macOSの一般的なアプリケーション(アプリケーションバンドル)を起動する場合はアプリケーションのパスを指定しても起動できない。openコマンド、またはバンドル内部の実行バイナリを指定する必要がある
以下はChromeのアプリモードでGMailを開くplistの設定である
openコマンドを使う例
<key>ProgramArguments</key> <array> <string>open</string> <string>-na</string> <string>Google Chrome</string> <string>--args</string> <string>--app=https://mail.google.com/mail/u/0/#inbox</string> </array>
バンドル内部の実行バイナリを指定する場合
<key>ProgramArguments</key> <array> <string>/Applications/Google Chrome.app/Contents/MacOS/Google Chrome</string> <string>--app=https://mail.google.com/mail/u/0/#inbox</string> </array>
注意点
- 外部ストレージにアクセスするのは避ける
~/Desktop
や~/Documents
にアクセスしないようにする
例えばDocuments以下のスクリプトファイルを起動する場合で
<key>Program</key> <string>/Users/nullpon/Documents/cron.sh</string>
cron.shがzshのスクリプトだった場合
#!/bin/zsh echo hoge
この場合/bin/zsh
がDocumentsディレクトリへのアクセス権限を持っていなければならない。
このスクリプトをターミナルで起動した場合、ターミナルからzshに権限が渡されるため起動可能だが、launchdで起動する場合zsh自体が権限を持っていなければならない。
権限がないと以下のようなエラーが出る
/bin/zsh: can't open input file: /Users/nullpon/Documents/cron.sh
そしてコマンドに権限を付与するのは手間がかかる上に、セキュリティ的にもあまり推奨されないのでできれば避けたい(マルウェアが設置するスクリプトにも許可が与えられてしまうため)。最初の例のように ~/apps
のようなディレクトリを切ってそこに置くのを推奨する