1 minute read

前言

login item 重複、launchctl load 失敗、plist 權限錯誤,是 macOS 工程師常見困擾。本文整理實戰排查流程。

常見問題與解法

1. launchctl load 失敗

症狀:

$ launchctl load ~/Library/LaunchAgents/com.example.myapp.plist
Load failed: 5: Input/output error

排查步驟:

# 檢查 plist 語法
plutil -lint ~/Library/LaunchAgents/com.example.myapp.plist

# 檢查權限
ls -la ~/Library/LaunchAgents/com.example.myapp.plist
# 應該是 -rw-r--r-- (644)

# 修正權限
chmod 644 ~/Library/LaunchAgents/com.example.myapp.plist

2. Login Item 重複

症狀: 應用程式在登入時啟動多次

解法:

# 列出所有 launch agents
launchctl list | grep com.example

# 移除重複項目
launchctl bootout gui/$(id -u) ~/Library/LaunchAgents/com.example.myapp.plist

# 清理 Login Items
osascript -e 'tell application "System Events" to delete login item "MyApp"'

3. 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.myapp</string>

    <key>ProgramArguments</key>
    <array>
        <string>/usr/local/bin/myapp</string>
        <string>--daemon</string>
    </array>

    <key>RunAtLoad</key>
    <true/>

    <key>KeepAlive</key>
    <true/>

    <key>StandardOutPath</key>
    <string>/tmp/myapp.log</string>

    <key>StandardErrorPath</key>
    <string>/tmp/myapp.error.log</string>
</dict>
</plist>

4. 新版 macOS 的變化

macOS 10.10+ 使用新的 launchctl 語法:

# 舊語法(已棄用)
launchctl load ~/Library/LaunchAgents/com.example.myapp.plist
launchctl unload ~/Library/LaunchAgents/com.example.myapp.plist

# 新語法
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.example.myapp.plist
launchctl bootout gui/$(id -u) ~/Library/LaunchAgents/com.example.myapp.plist

# 啟動/停止服務
launchctl kickstart gui/$(id -u)/com.example.myapp
launchctl kill SIGTERM gui/$(id -u)/com.example.myapp

5. 除錯技巧

# 查看服務狀態
launchctl print gui/$(id -u)/com.example.myapp

# 查看系統日誌
log show --predicate 'subsystem == "com.apple.launchd"' --last 1h

# 手動執行測試
/usr/local/bin/myapp --daemon

常見錯誤碼

錯誤碼 說明
5 Input/output error(權限或路徑問題)
37 Operation already in progress
113 Could not find specified service

結論

launchctl 問題通常來自權限設定或 plist 格式錯誤,善用 plutillog show 可以快速定位問題。