
十里(5km)macOS
macOS 自启动服务配置指南
最近在 Mac 上配置 MCP 服务的自启动,之前也搞过 frp 的自启动,花了点时间整理了 launchctl 的用法,自启动服务配置看这篇就够用了,让 AI 看了帮你搞也行。
460次点击0分钟阅读
配置放哪里
macOS 用 launchd 管理自启动,配置文件有三个地方可以放:
踩坑提醒:同一个服务只放一个地方。 我之前在两个目录都放了 frpc 的配置,结果启动了两个进程,服务端一直报 "proxy already exists",排查了好久才发现。
plist 模板
探索了一下,这个模板基本够用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26<?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.yourname.servicename</string> <key>ProgramArguments</key> <array> <string>/path/to/program</string> <string>-c</string> <string>/path/to/config</string> </array> <key>RunAtLoad</key> <true/> <key>KeepAlive</key> <true/> <key>StandardOutPath</key> <string>/tmp/servicename.log</string> <key>StandardErrorPath</key> <string>/tmp/servicename.err</string> </dict> </plist>
几个关键配置:
Label:唯一标识,建议用反向域名格式KeepAlive:崩溃后自动重启StandardOutPath/StandardErrorPath:日志路径,强烈建议加上,不然出问题只能盲猜
常用命令
新版 macOS 推荐用 bootstrap/bootout,老的 load/unload 有时会报奇怪的错误。
1 2 3 4 5 6 7 8 9 10 11 12# 系统级服务 sudo launchctl bootstrap system/ /Library/LaunchDaemons/com.xxx.plist sudo launchctl bootout system/com.xxx sudo launchctl kickstart -k system/com.xxx # 重启 # 用户级服务 launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.xxx.plist launchctl bootout gui/$(id -u)/com.xxx # 查看状态 launchctl list | grep servicename plutil -lint xxx.plist # 验证语法
添加服务的流程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15# 1. 先手动跑一下,确认程序本身没问题 /path/to/program -c /path/to/config # 2. 创建 plist # 3. 设置权限(系统级服务必须) sudo chmod 644 /Library/LaunchDaemons/com.xxx.plist sudo chown root:wheel /Library/LaunchDaemons/com.xxx.plist # 4. 加载 sudo launchctl bootstrap system/ /Library/LaunchDaemons/com.xxx.plist # 5. 确认 launchctl list | grep xxx cat /tmp/xxx.log
踩坑记录
加载时报 Input/output error
试了各种方法都不行,最后发现换个 Label 名就好了。猜测是系统缓存了之前的服务名。
launchctl list 显示退出码 1
不一定是当前状态,可能是上一次的退出码。看日志确认实际运行情况。
服务一直重启
程序启动后立刻退出了。加上日志输出,看看具体报什么错。
小结
- 配置只放一个位置
- 一定要加日志输出
- 加载前先手动测试
- 遇到奇怪的加载失败,换个 Label 名试试

