Appearance
macOS launchctl 完全指南:系统服务管理利器

launchctl 是 macOS 的系统服务管理工具,用于加载、卸载、启动和停止守护进程(Daemons) 和代理(Agents)。它基于 launchd 服务管理系统,是 macOS 的核心组件之一。
如果你是 macOS 开发者、运维人员或高级用户,掌握 launchctl 可以让你更好地管理系统服务和自动化任务。
1. launchd 与 launchctl 的关系
launchd:macOS 的初始化系统,负责系统启动时加载服务,管理后台进程(类似 Linux 的systemd)。launchctl:命令行工具,用于与launchd交互,管理服务。
2. launchd 服务类型
| 类型 | 存储位置 | 运行权限 | 用途 |
|---|---|---|---|
| 系统守护进程(System Daemons) | /System/Library/LaunchDaemons/ | root | 系统级后台服务 |
| 用户守护进程(User Daemons) | /Library/LaunchDaemons/ | root | 管理员安装的全局服务 |
| 系统代理(System Agents) | /System/Library/LaunchAgents/ | 当前用户 | 系统提供的用户级服务 |
| 用户代理(User Agents) | ~/Library/LaunchAgents/ | 当前用户 | 用户自定义的后台任务 |
3. launchctl 基本用法
3.1 加载/卸载服务
bash
# 加载服务(不自动启动)
launchctl load /path/to/plist
# 立即加载并启动(推荐方式,macOS 10.10+)
launchctl bootstrap gui/$UID /path/to/plist
# 旧版 macOS 使用 -w 参数
launchctl load -w /path/to/plist
# 卸载服务
launchctl unload /path/to/plist
launchctl bootout gui/$UID /path/to/plist # macOS 10.10+3.2 启动/停止服务
bash
# 启动服务(需先加载)
launchctl start com.example.service
# 停止服务
launchctl stop com.example.service3.3 查看服务状态
bash
# 列出所有已加载的服务
launchctl list
# 查看某个服务的状态
launchctl print gui/$UID/com.example.service3.4 调试服务
bash
# 查看日志(配合 log 命令)
log stream --predicate 'sender == "com.example.service"'
# 直接运行服务(测试配置是否正确)
/path/to/your/daemon -f4. plist 配置文件详解
launchd 服务使用 .plist(Property List)文件定义,通常存放在对应的服务目录中。
示例:一个简单的 plist 文件
xml
<?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>/var/log/myapp.log</string>
<key>StandardErrorPath</key>
<string>/var/log/myapp.err</string>
</dict>
</plist>关键配置项说明
| 参数 | 说明 |
|---|---|
| Label | 服务唯一标识(如 com.example.myapp) |
| ProgramArguments | 要执行的命令(数组形式) |
| RunAtLoad | 是否在加载时立即运行 |
| KeepAlive | 是否崩溃后自动重启 |
| StartInterval | 定时运行间隔(秒) |
| StartCalendarInterval | 日历定时运行 |
| StandardOutPath | 标准输出日志路径 |
| StandardErrorPath | 错误日志路径 |
4.1 实战案例:APIServer 后台服务配置
以下是一个真实生产环境中使用的 launchd 配置文件,用于管理一个 API 后台服务:
xml
<?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>Description</key>
<string>APIServer - 后台服务</string>
<key>Disabled</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>Label</key>
<string>flower.com.apiserver</string>
<key>ProcessType</key>
<string>Background</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/apiserver/apiserver.darwin.amd64</string>
<string>--config-dir</string>
<string>/usr/local/etc/apiserver</string>
<string>--config-name</string>
<string>config.yaml</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>StandardErrorPath</key>
<string>/usr/local/var/log/apiserver.log</string>
<key>StandardOutPath</key>
<string>/usr/local/var/log/apiserver.log</string>
<key>Version</key>
<string>v0.1.0</string>
<key>WorkingDirectory</key>
<string>/usr/local/var</string>
</dict>
</plist>配置项解读
| 配置项 | 值 | 说明 |
|---|---|---|
Label | flower.com.apiserver | 服务唯一标识,遵循反向域名命名规范 |
Description | APIServer - 后台服务 | 服务描述,便于识别 |
ProgramArguments | [/usr/local/bin/apiserver/..., --config-dir, ...] | 完整的命令行参数,支持传递配置文件路径 |
WorkingDirectory | /usr/local/var | 指定服务运行时的工作目录 |
KeepAlive | true | 进程异常退出时自动重启,保证服务高可用 |
RunAtLoad | true | 服务加载后立即启动,适合开机自启场景 |
ProcessType | Background | 标记为后台进程,系统会给予适当的资源调度优先级 |
Disabled | true | 默认禁用,需要手动启用(可通过 launchctl enable 开启) |
StandardOutPath / StandardErrorPath | /usr/local/var/log/apiserver.log | 标准输出和错误输出合并到同一个日志文件,便于统一查看 |
该配置文件的使用方式
bash
# 1. 将 plist 文件放到对应的服务目录
sudo cp flower.com.apiserver.plist /Library/LaunchDaemons/
# 2. 加载并启用服务(注意:Disabled 为 true,需要先启用)
sudo launchctl enable system/flower.com.apiserver
sudo launchctl bootstrap system /Library/LaunchDaemons/flower.com.apiserver.plist
# 3. 查看服务状态
sudo launchctl print system/flower.com.apiserver
# 4. 查看服务日志
tail -f /usr/local/var/log/apiserver.log💡 注意
该服务是系统级守护进程(System Daemon),需要使用 sudo 权限管理,且配置文件应存放在 /Library/LaunchDaemons/ 目录下。
5. 常见实战用例
5.1 开机自启动脚本
bash
# 1. 创建 plist 文件
cat > ~/Library/LaunchAgents/com.example.myscript.plist <<EOF
<?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.myscript</string>
<key>ProgramArguments</key>
<array>
<string>/bin/zsh</string>
<string>-c</string>
<string>echo "Hello, launchd!" >> ~/mylog.txt</string>
</array>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>
EOF
# 2. 加载并启动
launchctl bootstrap gui/$UID ~/Library/LaunchAgents/com.example.myscript.plist5.2 定时任务(替代 cron)
xml
<!-- 每 1 小时运行一次 -->
<key>StartInterval</key>
<integer>3600</integer>
<!-- 或者每天 2:00 AM 运行 -->
<key>StartCalendarInterval</key>
<dict>
<key>Hour</key>
<integer>2</integer>
<key>Minute</key>
<integer>0</integer>
</dict>5.3 管理 Homebrew 服务
bash
# Homebrew 使用 launchctl 管理服务
brew services list # 查看服务
brew services start nginx # 启动
brew services stop nginx # 停止6. 常见问题与调试技巧
6.1 launchctl load 和 bootstrap 的区别
load(旧版)和bootstrap(新版)功能类似,但bootstrap是推荐方式(macOS 10.10+)。bootout对应unload。
6.2 权限问题
- System Daemons 需要
sudo:bashsudo launchctl load /Library/LaunchDaemons/com.example.service.plist - User Agents 不需要 root 权限。
6.3 调试技巧
检查 plist 格式:
bash
plutil -lint /path/to/plist查看服务日志:
bash
tail -f /var/log/system.log强制重新加载服务(谨慎使用):
bash
sudo launchctl kickstart -k system/com.apple.audio.coreaudiod7. 服务依赖管理
在某些场景下,你可能需要确保一个服务启动时,另一个服务已经成功运行。关于 macOS 环境下使用 launchctl 管理服务时如何实现服务依赖,请参考:launchctl 服务依赖配置详解
8. 总结
launchctl是 macOS 的服务管理工具,基于launchd。- 通过
.plist文件定义服务,支持开机启动、定时任务、进程守护。 - 推荐使用
bootstrap/bootout(macOS 10.10+)。 - 调试时注意权限、日志、plist 语法。
掌握 launchctl 可以更好地管理系统服务和自动化任务,适用于开发者、运维和高级用户。
