投稿

macOS の Background Items 表示名は plist の ProgramArguments で決まる

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.sh

plist を以下のように直す。

<key>ProgramArguments</key>
<array>
    <string>/Users/me/.local/scripts/my-queue-worker.sh</string>
</array>

/bin/zsh の行を削除しただけ。shebang が #!/bin/zsh なので、launchd がそのまま zsh で実行してくれる。

リロードは bootoutbootstrap で行う(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 の中身

トレンドのタグ