はじめに
以前、下記の通り、ディレクトリを監視してGitにコミットするメールアドレスを変更するスクリプトを作成しました。
このスクリプトは非常に便利なので、忘れずに常に起動していてほしいと思っています。できればシステムの起動またはログインと同時に常駐プロセスとして起動したいですね。そこで今回は macOS でこのプログラムを常駐プロセスにする方法を検討します。
方針
LaunchAgents で起動する
macOSには launchd
というサービス管理フレームワークが搭載されています。 launchd
は init
や inetd
、 crond
などの置き換えを目的としたもので、システム起動時やログイン時におけるプロセスの起動や定期実行を行うことができます。詳しい説明は他の記事に譲りますが、ここではユーザーレベルのプロセスの起動のためにはこの仕組みを利用するべきとだけ理解していただければ十分です。
launchd
の設定ファイルは通称 launchd.plist
と呼ばれます。 .plist
はプロパティリストと呼ばれるmacOS全般で使われる設定ファイルの拡張子で、現在ではXML形式で記述されています。
実装
そんなこんなで、下記のようなプロパティリストを作成しました。このファイルを任意のファイル名(ここでは watch-git-email.plist
)で ~/Library/LaunchAgents/
に保存してください。
<?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>watch-git-email</string>
<key>ProgramArguments</key>
<array>
<string>/ABSOLUTE/PATH/TO/watch-git-email.sh</string>
<string>/ABSOLUTE/PATH/TO/PARENT/DIRECTROTY</string>
<string>expect-email@example.com</string>
</array>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>
十分とは言えませんが、これで必要な項目は揃っています。簡単ですね。
実行
プロセスを起動させるためには下記のコマンドを実行します。 launchctl
は launchd
のための管理コマンドと理解しておけばだいたい大丈夫です。
$ launchctl load ~/Library/LaunchAgents/watch-git-email.plist
また、このディレクトリに保存しておけば、ログイン時に自動的にユーザー権限で実行されます。
停止
プロセスの停止には下記のコマンドを実行します。起動時との違いはサブコマンドが load
→ unload
になるだけです。
$ launchctl unload ~/Library/LaunchAgents/watch-git-email.plist
解説
launchd.plist
設定ファイルの記述内容について軽く解説していきます。今回の目的に際してはこの程度の記述で実行できますが、もっと詳細に管理したいときは、ぜひlaunch.plistのマニュアルページでご確認ください。
launchd
では登録されたプログラムを実行する単位を「ジョブ」と呼んでいます。ジョブ1つに対してプロパティリストが1つと考えてください。
ジョブの名称 - Label
ジョブには固有の名称をつける必要がありますので、これは必須項目です。この Label
の値はファイル名と同一であることが期待されているようです。つまりファイル名は <Label>.plist
ということですね。前述のファイルのファイル名もそのようになっていることに注目してください。
<key>Label</key>
<string>watch-git-email</string>
実行するコマンド - ProgramArguments
プログラムの実行方法を記述する項目です。コマンドと引数をそれぞれ配列の別要素として記述します。 $HOME
などの環境変数には期待せず、絶対PATHを記載してください。相対PATHで記載する方法もありますが、ここでは単純化のためにこうしてください。引数を取らない場合は Program
というkeyを使うことができ、当然ながら ProgramArguments
か Program
のどちらかが記載されている必要があります。
<key>ProgramArguments</key>
<array>
<string>/ABSOLUTE/PATH/TO/watch-git-email.sh</string>
<string>/ABSOLUTE/PATH/TO/PARENT/DIRECTROTY</string>
<string>expect-email@example.com</string>
</array>
ロード時に実行する - RunAtLoad
launchd
がプロパティリストをロードした時に実行するか否かを指定します。デフォルトの挙動では launchd
がロードした時にはジョブを登録するだけで、実行はしません。ロードした時に実行させたい場合は、この値を true
にする必要があります。
crond
のように定期実行させる場合には、ロード時には実行させる必要がないので、記載する必要はありません。(デフォルトの挙動になる)
<key>RunAtLoad</key>
<true/>
終わりに
launchd start
というサブコマンドとか、保存するディレクトリによって起動するタイミングなどが違うといったことも説明したかったという気持ちもありますが、できるだけシンプルに説明するためにけっこうな部分を省きました。プログラムの自動起動が成功したら、改めて公式ドキュメントを読むことをおすすめします。