macOSには、アプリケーションやスクリプト、バックグラウンドサービスなどを自動的に起動・管理する「launchd(ローンチディー)」という仕組みがあります。
Macを使っていて「ログインしたら自動的にスクリプトを実行したい」「定期的にプログラムを動かしたい」「バックグラウンドでサービスを常駐させたい」といった場合に利用できます。
この記事では、macOSのlaunchdとは何なのか、launchctlやplistとの関係、LaunchAgentsとLaunchDaemonsの違いなどをわかりやすく解説します。
launchdとは
launchdは、macOSでプロセスやサービスの起動・管理を担当するシステムです。
Macの起動時やユーザーのログイン時、指定した条件を満たしたときなどに、あらかじめ設定されたプログラムを起動できます。
launchd自体がすべての実行内容を直接記述しているわけではありません。基本的には「何を、どのような条件で起動するのか」を設定ファイルに記述し、その設定に従ってlaunchdがジョブやサービスを管理します。
開発者が作成したスクリプトの自動実行だけでなく、macOS内部のさまざまなサービス管理にもlaunchdが使われています。
launchdでできること
launchdを利用すると、さまざまな条件でプログラムを実行できます。
代表的な用途には次のようなものがあります。
- ユーザーのログイン時にプログラムを実行する
- システム起動時にバックグラウンドサービスを起動する
- 一定間隔でスクリプトを実行する
- 指定した時刻に処理を実行する
- 特定の条件に応じてプログラムを起動する
- 必要に応じてサービスを継続的に管理する
そのため、サーバー処理や開発環境の自動化、バックアップ処理、定期的なデータ処理など幅広い用途に利用できます。
launchdとlaunchctlの違い
launchdについて調べると「launchctl」というコマンドもよく登場します。
両者は役割が異なります。
launchdは、macOS上でサービスやジョブを管理する仕組みそのものです。
一方のlaunchctlは、launchdとやり取りしてサービスやジョブを管理するためのコマンドラインツールです。
つまり、
「launchd=サービスを管理する仕組み」
「launchctl=launchdを操作するためのコマンド」
と考えると理解しやすいでしょう。
ターミナルからlaunchctlを使用することで、サービスの登録や解除、状態確認などを行えます。
plistとは
launchdを利用するうえで重要になるのが「plist」です。
plistは「Property List」の略で、AppleのOSで設定情報などを保存するために使われるファイル形式です。
launchdでは、どのプログラムをどのような条件で実行するのかをplist形式で定義します。
launchd用のplistでは、たとえば次のような情報を設定できます。
- ジョブを識別するLabel
- 実行するプログラムや引数
- 読み込み時に実行するか
- 実行スケジュール
- 標準出力の保存先
- 標準エラー出力の保存先
- ジョブを維持するための条件
ファイルの拡張子は「.plist」です。
たとえば独自の処理を登録する場合、
com.example.myscript.plist
のような名前を付けることがあります。
LaunchAgentsとは
launchdには「LaunchAgents」という仕組みがあります。
LaunchAgentsは、基本的にユーザーのログインセッションに関連する処理を実行するときに使用されます。
ユーザーごとのLaunchAgentsを配置する代表的なディレクトリは次の場所です。
~/Library/LaunchAgents/
「~」は現在のユーザーのホームディレクトリを表します。
そのため、たとえばユーザー名が「taro」であれば、実際のパスは次のようになります。
/Users/taro/Library/LaunchAgents/
特定のユーザーがログインしている環境で実行したい処理などに利用されます。
LaunchDaemonsとは
LaunchDaemonsは、ユーザーのログインセッションとは独立したシステムレベルのバックグラウンドサービスなどに使用されます。
代表的な配置場所は次のとおりです。
/Library/LaunchDaemons/
LaunchDaemonsはシステム側で動作するサービスに利用されるため、設定や操作に管理者権限が必要になる場合があります。
ユーザーのログイン環境に依存する処理と、システム全体で動作させる処理では目的が異なるため、LaunchAgentsとLaunchDaemonsを適切に使い分けることが重要です。
LaunchAgentsとLaunchDaemonsの違い
LaunchAgentsとLaunchDaemonsの大きな違いは、実行される環境です。
LaunchAgentsはユーザーのログインセッションに関連して動作します。
一方、LaunchDaemonsはシステムレベルのサービスとして動作し、特定ユーザーのログインを前提としません。
ユーザー単位の自動処理であればLaunchAgents、システム全体で動作させるバックグラウンドサービスであればLaunchDaemonsというように、処理の目的に応じて選択します。
launchdのplistの基本例
ユーザーがログインした環境でシェルスクリプトを自動実行する場合、たとえば次のような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>com.example.myscript</string>
<key>ProgramArguments</key>
<array>
<string>/bin/zsh</string>
<string>/Users/taro/scripts/test.sh</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>StandardOutPath</key>
<string>/tmp/myscript.log</string>
<key>StandardErrorPath</key>
<string>/tmp/myscript-error.log</string>
</dict>
</plist>
この例では、ProgramArgumentsで実行するコマンドと引数を指定しています。
RunAtLoadをtrueにすることで、ジョブが読み込まれた際に実行されるよう設定しています。
また、StandardOutPathとStandardErrorPathによって、標準出力と標準エラー出力の保存先を指定しています。
実際に使用する場合は、ユーザー名やスクリプトの保存場所などを自分の環境に合わせて変更する必要があります。
launchctlでジョブを管理する
launchdのジョブをターミナルから管理するときにはlaunchctlを使用します。
ユーザーのLaunchAgentを現在のGUIログインセッションに登録する場合は、たとえば次のようにbootstrapサブコマンドを利用できます。
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.example.myscript.plist
登録したジョブを解除する場合はbootoutを使用できます。
launchctl bootout gui/$(id -u) ~/Library/LaunchAgents/com.example.myscript.plist
特定のサービスについてlaunchdが保持している情報を確認する場合は、次のようにprintを利用できます。
launchctl print gui/$(id -u)/com.example.myscript
launchctlには多数のサブコマンドがあり、対象となるドメインやジョブの種類によって適切な操作方法が異なります。
launchdで定期実行する方法
launchdは、プログラムを一定間隔で実行する用途にも利用できます。
たとえばplistの「StartInterval」を利用すると、秒単位の間隔を指定してジョブの実行条件を設定できます。
<key>StartInterval</key>
<integer>3600</integer>
この場合は3600秒、つまり1時間を基準とした実行条件になります。
また「StartCalendarInterval」を利用すると、カレンダー上の時刻を条件として実行する設定も可能です。
ただし、launchdのスケジュール実行はcronとまったく同じ挙動ではありません。Macのスリープ状態なども考慮し、用途に合った設定を選ぶ必要があります。
launchdとcronの違い
Unix系OSで定期実行といえばcronが広く知られています。
macOSにもcron関連の仕組みは存在しますが、macOSのサービスやジョブを管理する仕組みとしてAppleが提供しているのがlaunchdです。
launchdでは単純な時刻指定だけでなく、サービスの起動や維持など、cronより広い範囲のジョブ管理を扱えます。
そのため、macOS上で新しく自動実行環境を構築する場合には、launchdを理解しておくと便利です。
launchdを利用するときの注意点
launchdでスクリプトを実行するときは、ターミナルから手動実行した場合と環境が異なることに注意が必要です。
特に問題になりやすいのが環境変数やPATHです。
ターミナルでは正常に動くコマンドでも、launchd経由ではコマンドが見つからず失敗する場合があります。
そのため、実行ファイルやスクリプトについては可能な限り絶対パスを使用し、必要な環境変数についても明示的に設定することが重要です。
また、ファイルやディレクトリへのアクセスについてはmacOSの権限管理やプライバシー保護機能の影響を受ける場合があります。
plistに問題がないか確認する
作成したplistの構文に問題がないか確認したい場合は、macOSの「plutil」コマンドを利用できます。
たとえば次のように実行します。
plutil -lint ~/Library/LaunchAgents/com.example.myscript.plist
構文上の問題がなければ、plistが適切な形式になっていることを確認できます。
ただし、plistのXML構文が正しいことと、launchdのジョブとして意図どおりに動作することは別です。
実行されない場合は、launchctlによる状態確認に加え、標準出力や標準エラー出力、システムログ、実行ファイルのパスや権限なども確認する必要があります。
launchdはMacの自動化に役立つ仕組み
launchdは、macOSにおけるプロセスやサービスの起動・管理を担う重要な仕組みです。
ユーザーのログインに合わせてスクリプトを起動したり、バックグラウンドサービスを管理したり、指定した条件で処理を実行したりできます。
launchdを理解するうえでは、「launchd」「launchctl」「plist」「LaunchAgents」「LaunchDaemons」の関係を整理しておくことがポイントです。
ユーザー単位の処理なのか、システムレベルのサービスなのかを判断したうえで適切な場所にplistを配置し、launchctlを使って管理します。
Macでシェルスクリプトやプログラムの自動実行を行いたい場合、launchdは覚えておきたいmacOSの基本機能の一つです。


コメント