macOS の Background Items 表示名は plist の ProgramArguments で決まる
まとめ
- macOS「システム設定 → 一般 → ログイン項目と機能拡張 → バックグラウンドでの実行を許可」に表示される名前は、plist の
LabelではなくProgramArguments[0]の basename から取られる ProgramArguments[0]を/bin/zshにして第二要素にスクリプトを渡すと、表示名は「zsh」に丸め込まれて識別不能になる- スクリプトに shebang を書いて実行ビットを付け、
ProgramArguments[0]に スクリプト本体のパス を直接置けば、basename がそのまま表示名になる
起きたこと
自作の launchd ジョブをいくつか登録していて、System Settings 上では識別可能な名前で並んで見えていた。
my-server
my-snapshot-jobところが新しく追加したキュー処理用の LaunchAgent だけ、いくらリストを探しても出てこない。plist の Label には com.user.my-queue-worker と入れているのに、Background Items の一覧には影も形もなかった。
「ファイル名や Label の付け方が悪いのかな」と最初は疑ったが、原因は別だった。
何が違ったのか
それぞれの plist の ProgramArguments を並べると、ひと目で違いが見える。
ちゃんと表示される側
<key>ProgramArguments</key>
<array>
<string>/Users/me/MyApp/bin/my-server</string>
</array>「zsh」に丸められて見つけられない側
<key>ProgramArguments</key>
<array>
<string>/bin/zsh</string>
<string>/Users/me/.local/scripts/my-queue-worker.sh</string>
</array>macOS の Background Items リストは、登録されたジョブを ProgramArguments[0] の実行ファイル名(basename) でグルーピングして表示しているらしい。/bin/zsh を先頭に置いてしまうと「zsh で動いている何か」としてまとめられ、個別のジョブとしては事実上見えなくなる。
Label キーは launchctl の内部識別子としては効くが、UI の表示名には使われないということ。
修正方法
スクリプトに shebang と実行ビットがあれば、ProgramArguments[0] に スクリプト本体のパスを直接 置けば良い。
$ head -1 ~/.local/scripts/my-queue-worker.sh
#!/bin/zsh
$ ls -l ~/.local/scripts/my-queue-worker.sh
-rwxr-xr-x 1 me staff 2663 ... my-queue-worker.shplist を以下のように直す。
<key>ProgramArguments</key>
<array>
<string>/Users/me/.local/scripts/my-queue-worker.sh</string>
</array>/bin/zsh の行を削除しただけ。shebang が #!/bin/zsh なので、launchd がそのまま zsh で実行してくれる。
リロードは bootout → bootstrap で行う(macOS Catalina 以降の流儀)。
launchctl bootout gui/$UID ~/Library/LaunchAgents/com.user.my-queue-worker.plist
launchctl bootstrap gui/$UID ~/Library/LaunchAgents/com.user.my-queue-worker.plist
launchctl print gui/$UID/com.user.my-queue-worker | grep -E "program|state"再ロード後、Background Items の一覧に my-queue-worker.sh という名前で並ぶようになった。
拡張子を消したい場合
.sh が表示されるのが気持ち悪ければ、拡張子なしのシンボリックリンクを貼ってそれを ProgramArguments[0] に指定する手がある。
ln -s ~/.local/scripts/my-queue-worker.sh \
~/.local/bin/my-queue-workerこれで Background Items 上は my-queue-worker と表示される。
教訓
Labelは内部 ID。UI の表示名はProgramArguments[0]- インタプリタ (
/bin/zsh,/usr/bin/python3等) を先頭に置くな。shebang を活用してスクリプトを直接実行ファイル化する - 「ファイル名やラベルを変えたら見えるのでは」は罠。直すのは plist の
ProgramArgumentsの中身