加载、卸载、查看和重启 launchd 管理的 agent 与 daemon。
launchd 是 macOS 的 PID 1,负责开机启动、按需拉起和守护进程。LaunchAgent 以登录用户身份运行、可访问图形会话,放在 ~/Library/LaunchAgents(当前用户)或 /Library/LaunchAgents(所有用户);第三方 LaunchDaemon 以 root 运行、没有图形会话,放在 /Library/LaunchDaemons。plist 里的 Label 必须唯一,命令中用它定位任务,文件名通常与 Label 保持一致。
两套接口不要混用:旧的 launchctl load/unload [-w] 仍可用但已不推荐;新接口按 domain 操作,bootstrap 加载、bootout 卸载、kickstart -k 重启、print 查看、enable/disable 控制是否允许加载。图形登录用户用 gui/$(id -u),系统守护进程用 system。同一个任务先用 load 再用 bootstrap 会报 already loaded,应先统一卸载。
影响范围:
bootout和unload会立即停止对应任务;unload -w会把禁用状态持久写入 launchd 的覆盖记录,重启或重新登录后仍不加载。系统级 Daemon 可能承载网络、远程登录、备份或安全软件,卸载后可能失去远程管理通道。前置条件:先确认 Label、plist 路径和当前 domain,保留 plist 备份,并确保有本地控制台或可恢复的远程通道。恢复方式:bootstrap/load重新加载,enable清除禁用状态,必要时恢复 plist 的Disabled键;不要用kill -9代替卸载。
# 1. 列出当前用户的 job;PID 为 - 表示未运行,Status 是上次退出码
% launchctl list | grep com.example
% launchctl print gui/$(id -u)/com.example.agent
# 2. 新接口:加载当前用户的 LaunchAgent
% launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.example.agent.plist
# 3. 新接口:卸载;标签和 plist 路径两种写法都可以
% launchctl bootout gui/$(id -u)/com.example.agent
# 4. 重启正在运行的任务;-k 先杀掉再启动
% launchctl kickstart -k gui/$(id -u)/com.example.agent
# 5. 系统级 LaunchDaemon 必须 sudo,并在 system domain 操作
% sudo launchctl bootstrap system /Library/LaunchDaemons/com.example.daemon.plist
% sudo launchctl print system/com.example.daemon
# 6. 旧接口:-w 会持久覆盖 plist 里的 Disabled 键
% launchctl load -w ~/Library/LaunchAgents/com.example.agent.plist
% launchctl unload -w ~/Library/LaunchAgents/com.example.agent.plist
# 7. 确认任务是否被 disable,这是“怎么都起不来”的常见原因
% launchctl print-disabled system | grep com.example
system domain,应用会报找不到窗口服务器(常见错误码 -600);GUI 任务必须放 gui/$UID,并由已登录用户加载。root:wheel、Agent 归当前用户,目录和文件不能被组或其他用户写。验证:ls -l,修正后再 bootstrap。launchctl list 的 Status 为 78 通常表示配置错误(EX_CONFIG),PID 为 - 还可能是任务被 disable;用 plutil -lint 文件.plist 检查语法,launchctl print 看失败原因,print-disabled 看是否被禁用。ProgramArguments 里不会展开 ~、$HOME,也不经过 shell;所有路径写绝对路径,重定向和管道要自己包一层脚本。kickstart -k 不一定重新读取文件,且 KeepAlive 为真时进程退出会被立刻拉起;可靠做法是 bootout 后重新 bootstrap,停服务也用 bootout,不要用 kill -9 硬扛。gui/$UID 任务时,如果该用户没有图形登录会话,domain 可能不存在;先在本地登录,或用 launchctl asuser 进入用户上下文。ps、kill — 查看和终止任务进程。caffeinate、pmset — 常驻任务的电源前提。defaults — 查看 launchd 相关偏好。systemctl、systemd 速查 — 对照服务管理模型。sc — 对照 Windows 服务控制。合上页面,先回答,再展开对照。
load/unload 与 bootstrap/bootout 是什么关系?为什么不能混用?launchctl list 里 Status 为 78、PID 为 -,下一步怎么查?~/Library/LaunchAgents 或 /Library/LaunchAgents;Daemon 以 root 运行、无图形会话,放 /Library/LaunchDaemons。bootstrap/bootout。plutil -lint 检查 plist,launchctl print 看具体错误,并核对权限、Label 和 ProgramArguments 路径。
小程序版
微信扫码,随时查命令