macOS 系统服务崩溃后无法自动恢复,需通过 AppleScript + launchd 实现精准检测、延迟判断与防循环重启;用 pgrep -x 检测进程存活,launchd 的 Crashed + ThrottleInterval 实现可控拉起,辅以日志排查根因。macOS 系统服务进程崩溃后无法自动恢复,系统本身不提供通用的“崩溃即重启”机制。但你可以通过组合 AppleScript + launchd 实现可控、防误触的自动拉起,关键在于**精准检测、延迟判断、防循环重启**,而不是简单粗暴地轮询重启。
用 AppleScript 检测并拉起指定服务进程
系统服务(如 `bluetoothd`、`networkd`、`accessibilityd`)通常以守护进程形式运行,不带 GUI,不能用 `application "XXX" is running` 判断。必须依赖 shell 命令检测:• 使用 pgrep -x 匹配精确进程名(比 -f 更可靠,避免误匹配)
• 示例:检查蓝牙守护进程是否存活:pgrep -x bluetoothd
• 若返回空,则进程已退出;返回 PID 数字则表示正常运行
• AppleScript 中调用:do shell script "pgrep -x bluetoothd > /dev/null && echo 1 || echo 0",结果为 "1" 即存活
用 launchd 替代无限循环脚本,更稳定省资源
AppleScript 的repeat 轮询会持续占用 CPU,且难以优雅退出。推荐改用 launchd plist 配置:
• 创建 plist 文件(如 ~/Library/LaunchAgents/local.restart.bluetoothd.plist)
• 设置 KeepAlive 键为字典,启用 Crashed 子键:<key>Crashed</key><true/>
• 指定 ProgramArguments 为启动命令:launchctl kickstart -k system/com.apple.bluetoothd 或 sudo launchctl load /System/Library/LaunchDaemons/com.apple.bluetoothd.plist
• 加载后执行:launchctl load ~/Library/LaunchAgents/local.restart.bluetoothd.plist
• launchd 会在进程异常退出时自动拉起,且默认限制每 10 秒最多重启 1 次,天然防无限循环
加装启动间隔熔断机制,避免雪崩式重启
某些服务(如第三方内核扩展引发的 `kernel_task` 高负载)可能造成连环崩溃。必须加入冷却逻辑:• 在 launchd plist 中添加:<key>ThrottleInterval</key><integer>30</integer>(单位秒),强制两次拉起至少间隔 30 秒
• 或在 AppleScript 中记录时间戳文件:do shell script "echo $(date +%s) > ~/Library/Caches/.bluetoothd_last_start"
• 每次启动前读取并比对:set lastTime to (do shell script "cat ~/Library/Caches/.bluetoothd_last_start 2>/dev/null || echo 0")
• 若距上次启动不足 5 秒,跳过本次拉起,并弹窗提醒:display alert "服务连续异常退出,请检查日志"
优先查日志定位根因,拉起只是临时兜底
自动重启掩盖问题,不能替代诊断:• 查崩溃线索:log show --predicate 'process == "bluetoothd"' --last 2h
• 看系统级报错:log show --predicate 'eventMessage contains "panic"' --last 1h
• 检查配置损坏:plutil -lint ~/Library/Preferences/com.apple.Bluetooth.plist,无效就删掉让系统重建
• 若是 MDM 或配置描述文件干扰,前往「系统设置 > 隐私与安全性 > 管理配置文件」中移除可疑项

















