Lazy loaded image
mac 服务管理工具 launchd
Words 1360Read Time 4 min
2025-9-29
2025-11-10
date
related_level
slug
type
relate_date
summary
status
tags
category
last_updated
Nov 10, 2025 10:02 PM
是否已更新
orginal_page
是否推荐
 
.plist 存放位置及其区别
  • Apple 官方软件系统级别服务
    • /System/Library/LaunchDaemons
    • /System/Library/LaunchAgents
  • 第三方系统级别服务(需要管理员权限)
    • /Library/LaunchDaemons
    • /Library/LaunchAgents
  • 用户级别服务
    • ~/Library/LaunchAgents
区分 <service-name><domain-target>, <service-target>
  • service-name 是指在服务 plist 文件中定义的 <key>Label<key> 唯一名称
  • domain-target 是指服务的命名空间
    • 基础系统域 system:需要以特权用户身份执行的服务
      • 对应路径 /System/Library
      • 对应路径 /Library
    • 非登录用户域 user/<uid>:需要以特定用户身份执行但无需用户为登录状态的服务
      • launchctl manageruid 获取当前用户 uid
    • 已登录用户域 gui/<uid>:需要以特定用户身份执行且需要用户为登录状态的服务
  • service-target 是指 <domain-target>/<service-name>
(可选)永久移除已禁用的项目条目
  • LaunchDaemon/LaunchAgent 中的项目 plist 中可以通过 Disabled 键设置应用默认启动状态
  • 通过 launchctl enable/disable 更改服务启动状态不会更改 plist 中的 Disabled 键值,而是在特定 disabled.plist 文件上存储当前状态
  • 因此项目即使卸载了也会显示启用其状态
    • launchctl print-disabled system | grep com.custom
    • launchctl print-disabled gui/501 | grep com.custom
  • sudo grep -rnw '/var/db/com.apple.xpc.launchd/' -e "com.custom"
  • 删除对应项
    • sudo vim /var/db/com.apple.xpc.launchd/disabled.plist
      • 系统命名空间
    • sudo vim /var/db/com.apple.xpc.launchd/disabled.<uid>.plist
      • 用户命名空间
    • sudo vim /var/db/com.apple.xpc.launchd/disabled.501.plist
      • 用户命名空间
  • 需要重启生效
    • sudo reboot
 

系统启动后待网络就绪后执行 rc.local 设置接口 en0 的 ipv6 默认路由

mac 设置为自动获取 ipv6 地址
  • networksetup -setv6automatic "Ethernet"
添加 /etc/rc.local 脚本
sudo vim /etc/rc.local
  • 等待 20s,等待 en0 接口加载
  • 自行更改对应 ipv6 路由地址及对应接口
  • sudo chmod +x /etc/rc.local
添加 /Library/LaunchDaemons 下的 plist,在网络就绪后再执行 /etc/rc.local
sudo vim /Library/LaunchDaemons/com.custom.rclocal.plist
  • chmod 644 /Library/LaunchDaemons/com.custom.rclocal.plist
  • plutil -lint /Library/LaunchDaemons/com.custom.rclocal.plist
    • 语法检查
launchd 加载并启用对应 plist 服务
  • launchctl print system | grep com.custom.rclocal
    • 先检查是否已加载,重复加载会报错 Load failed: 5: Input/output error
  • sudo launchctl bootstrap system /Library/LaunchDaemons/com.custom.rclocal.plist
    • load -w 已过时,用 bootstrap / enable 替代
      • load -w 加载并 enable 服务,下次启动时自动加载
  • launchctl enable system/com.custom.rclocal
    • 启用服务,下次启动时自动加载
  • launchctl disable system/com.custom.rclocal
    • 禁用服务,下次启动时不再加载
查看 plist 服务
  • sudo launchctl list | grep com.custom
  • sudo launchctl list com.custom.rclocal
  • launchctl print system/com.custom.rclocal
  • sudo launchctl kickstart system/com.custom.rclocal
    • 立即运行一次,无视条件
  • sudo launchctl kill 9 system/com.custom.rclocal
    • 强制杀死进程
修改后需要卸载后重新加载
  • sudo launchctl bootout system /Library/LaunchDaemons/com.custom.rclocal.plist
  • sudo launchctl bootstrap system /Library/LaunchDaemons/com.custom.rclocal.plist
查看 ipv6 路由表
  • netstat -rn -f inet6 | head -10
 

创建 step 自签证书续签定时任务

假设已安装 step,证书路径在 ~/stepca-certificates
  • brew install step
  • step ca bootstrap --ca-url https://ca.example.com:9000 --fingerprint <CA_FINGERPRINT> --install
    • 仅 install 无法被信任自签根证书
    • 打开应用 钥匙串访问,在(系统钥匙串)系统→证书 中找到对应根证书并双击打开,点击 信任 左侧 > 按钮展开并调整 使用此证书时 为 始终信任
添加续签证书脚本
  • mkdir -p ~/scripts/hourly
vim ~/scripts/hourly/renew.mac.sh
vim ~/scripts/hourly/after.renew.mac.sh
  • 自行添加续签后需要重新加载或启动的服务
  • chmod +x ~/scripts/hourly/renew.mac.sh ~/scripts/hourly/after.renew.mac.sh
step 续签并覆盖原证书时需要管理员权限
  • 会存在安全风险,自行判断
  • 修改脚本所有者为 root 用户
    • chown root ~/scripts/hourly/renew.mac.sh
  • sudo visudo 配置 sudoers 文件,添加以下行
    • <username> ALL=(ALL) NOPASSWD: /Users/<username>/scripts/hourly/renew.mac.sh
      • 无需密码
添加 ~/Library/LaunchAgents 下的 plist,launchd 加载并启用对应 plist 服务
  • launchctl print gui/501 | grep com.custom.renew.certs
    • 需要输入 uid 作为命名空间
      • launchctl manageruid 获取当前用户 uid
      • launchctl managerpid 获取当前 launchd pid
    • 先检查是否已加载,重复加载会报错 Load failed: 5: Input/output error
vim ~/Library/LaunchAgents/com.custom.renew.certs.plist
  • Disabled 键的默认值也是 false
  • 需要 sudo 执行,否则需要 renew 时会报错 no route to host
  • 每小时尝试续签一次
  • plutil -lint ~/Library/LaunchAgents/com.custom.renew.certs.plist
    • 语法检查
  • sudo launchctl bootstrap gui/501 ~/Library/LaunchAgents/com.custom.renew.certs.plist
    • load -w 已过时,用 bootstrap / enable 替代
      • load -w 加载并 enable 服务,下次启动时自动加载
  • launchctl enable gui/501/com.custom.renew.certs
    • 启用服务,下次启动时自动加载
  • launchctl disable gui/501/com.custom.renew.certs
    • 禁用服务,下次启动时不再加载
查看 plist 服务
  • launchctl list com.custom.renew.certs
  • launchctl print gui/501/com.custom.renew.certs
    • 详细信息
  • launchctl kickstart gui/501/com.custom.renew.certs
    • 立即运行一次,无视条件
  • cat /tmp/local.job.stdout && echo "\n" && cat /tmp/local.job.err
    • 查看日志
修改后需要卸载后重新加载
  • sudo launchctl bootout gui/501/com.custom.renew.certs
  • sudo launchctl bootstrap gui/501 ~/Library/LaunchAgents/com.custom.renew.certs.plist
可选,永久移除已禁用的项目条目
  • disable 项目即使卸载也会显示
  • /private/var/db/launchd.db/com.apple.launchd/overrides.plist
  • sudo grep -rnw '/private/var/db/com.apple.xpc.launchd/' -e "com.custom"
上一篇
uv 管理 python 环境
下一篇
高可用 step-ca 服务器

Comments
Loading...