macOS 自启动服务管理

macOS 使用 launchd 管理自启动服务,配置文件为 .plist 格式。

配置文件位置

  • 用户级别~/Library/LaunchAgents/
  • 系统级别/Library/LaunchAgents/
  • 系统守护进程/Library/LaunchDaemons/

查看服务

# 查看所有服务
launchctl list

# 查看特定服务
launchctl list | grep 应用名

添加自启动服务

  1. 创建 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>/path/to/your/app</string>
     </array>
     <key>RunAtLoad</key>
     <true/>
     <key>KeepAlive</key>
     <true/>
    </dict>
    </plist>
    
  2. 加载服务

    # 加载用户级别服务
    launchctl load ~/Library/LaunchAgents/com.example.myapp.plist
    

加载系统级别服务

sudo launchctl load /Library/LaunchDaemons/com.example.myapp.plist

### 移除自启动服务

1. **停止服务**
```bash
launchctl remove 服务名
# 或
sudo launchctl remove 服务名
  1. 删除配置文件

    rm ~/Library/LaunchAgents/服务名.plist
    # 或
    sudo rm /Library/LaunchAgents/服务名.plist
    sudo rm /Library/LaunchDaemons/服务名.plist
    

实战案例:RustDesk 自启动管理

查找 RustDesk 服务:

launchctl list | grep -i rustdesk
ls ~/Library/LaunchAgents/ | grep -i rustdesk
ls /Library/LaunchAgents/ | grep -i rustdesk
sudo ls /Library/LaunchDaemons/ | grep -i rustdesk

一键移除 RustDesk 自启动:

# 停止服务
launchctl remove com.rustdesk.service 2>/dev/null
launchctl remove com.carriez.RustDesk_server 2>/dev/null
sudo launchctl remove com.carriez.RustDesk_service 2>/dev/null

# 删除配置文件
rm ~/Library/LaunchAgents/com.rustdesk.service.plist 2>/dev/null
sudo rm /Library/LaunchAgents/com.carriez.RustDesk_server.plist 2>/dev/null
sudo rm /Library/LaunchDaemons/com.carriez.RustDesk_service.plist 2>/dev/null

# 验证清除结果
launchctl list | grep -i rustdesk

常用命令速查

# 查看服务状态
launchctl list 服务名

# 启动服务
launchctl start 服务名

# 停止服务
launchctl stop 服务名

# 重启服务
launchctl kickstart 服务名

# 卸载服务(临时)
launchctl unload 配置文件路径

# 加载服务
launchctl load 配置文件路径

注意事项

  • 系统级别操作需要 sudo 权限
  • 删除配置文件前建议备份
  • 重启后验证服务状态
  • 某些应用可能会重新创建自启动服务

添加自启动服务详解

服务添加步骤

  1. 创建 plist 文件
  2. 放置到对应目录
  3. 加载服务
  4. 验证运行状态

RustDesk 实际案例分析

LaunchAgent 配置(用户级别):

<!-- /Library/LaunchAgents/com.carriez.RustDesk_server.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.carriez.RustDesk_server</string>
        <key>LimitLoadToSessionType</key>
        <array>
          <string>LoginWindow</string>
          <string>Aqua</string>
        </array>
        <key>KeepAlive</key>
        <dict>
            <key>SuccessfulExit</key>
            <false />
            <key>AfterInitialDemand</key>
            <false />
        </dict>
        <key>RunAtLoad</key>
        <true />
        <key>ProgramArguments</key>
        <array>
            <string>/Applications/RustDesk.app/Contents/MacOS/RustDesk</string>
            <string>--server</string>
        </array>
        <key>WorkingDirectory</key>
        <string>/Applications/RustDesk.app/Contents/MacOS/</string>
    </dict>
</plist>

LaunchDaemon 配置(系统级别):

<!-- /Library/LaunchDaemons/com.carriez.RustDesk_service.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.carriez.RustDesk_service</string>
        <key>KeepAlive</key>
        <true/>
        <key>ProgramArguments</key>
        <array>
            <string>/bin/sh</string>
            <string>-c</string>
            <string>/Applications/RustDesk.app/Contents/MacOS/service</string>
        </array>
        <key>RunAtLoad</key>
        <true/>
        <key>WorkingDirectory</key>
        <string>/Applications/RustDesk.app/Contents/MacOS/</string>
        <key>StandardErrorPath</key>
        <string>/tmp/rustdesk_service.err</string>
        <key>StandardOutPath</key>
        <string>/tmp/rustdesk_service.out</string>
    </dict>
</plist>

关键配置项说明

配置项 作用 示例值
Label 服务唯一标识 com.carriez.RustDesk_server
RunAtLoad 启动时自动运行 true
KeepAlive 进程保活策略 true 或复杂字典
LimitLoadToSessionType 限制加载的会话类型 LoginWindow, Aqua
ProgramArguments 程序路径和参数 数组格式
WorkingDirectory 工作目录 /Applications/RustDesk.app/Contents/MacOS/
StandardOutPath 标准输出日志 /tmp/rustdesk_service.out
StandardErrorPath 错误输出日志 /tmp/rustdesk_service.err

部署策略对比

只添加 LaunchAgent

# 创建文件
sudo cp com.carriez.RustDesk_server.plist /Library/LaunchAgents/

# 加载服务
sudo launchctl load /Library/LaunchAgents/com.carriez.RustDesk_server.plist

特点

  • ✅ 用户登录后启动
  • ✅ 有 GUI 访问权限
  • ❌ 用户未登录时无法远程连接

只添加 LaunchDaemon

# 创建文件
sudo cp com.carriez.RustDesk_service.plist /Library/LaunchDaemons/

# 加载服务
sudo launchctl load /Library/LaunchDaemons/com.carriez.RustDesk_service.plist

特点

  • ✅ 系统启动即运行
  • ✅ 无需用户登录
  • ❌ 无 GUI 访问权限
  • ❌ 功能可能受限

同时添加两者(RustDesk 策略):

# 添加 LaunchAgent
sudo cp com.carriez.RustDesk_server.plist /Library/LaunchAgents/
sudo launchctl load /Library/LaunchAgents/com.carriez.RustDesk_server.plist

# 添加 LaunchDaemon  
sudo cp com.carriez.RustDesk_service.plist /Library/LaunchDaemons/
sudo launchctl load /Library/LaunchDaemons/com.carriez.RustDesk_service.plist

特点

  • ✅ 系统启动即有基础服务
  • ✅ 用户登录后有完整功能
  • ✅ 最佳的远程访问体验
  • ❌ 资源占用稍高

验证服务状态

# 检查服务是否加载
launchctl list | grep -i rustdesk

# 检查进程是否运行
ps aux | grep -i rustdesk

# 查看日志
tail -f /tmp/rustdesk_service.out
tail -f /tmp/rustdesk_service.err

最佳实践建议

  1. 远程访问应用:推荐双重部署(Agent + Daemon)
  2. 用户工具:只需 LaunchAgent
  3. 系统服务:只需 LaunchDaemon
  4. 日志管理:设置合适的日志路径
  5. 权限控制:根据需要选择部署级别