本文目录#
0. 相关背景知识#
0.1. Mac 中定义定时任务的几种方式#
- Launchd(官方推荐的方式)
- cron(重启后即失效,不推荐)
- brew services
本文介绍使用 Launchd 方式开启定时任务
0.1. 什么是 Launchd#
Launchd是 MacOS 用来管理系统和用户级别的守护进程的工具。
该工具由两部分组成:
- launchd
- launchd 主要有两个任务:
- 一是启动系统
- 二是加载和维护服务
- 系统启动时,launchd 会加载
/System/Library/LaunchDaemons
和/Library/LaunchDaemons
中的所有plist 文件,然后根据需要启动 launchctl。
- launchd 主要有两个任务:
- launchctl
- 在 launchd 中,对服务的控制集中在
launchctl
中。
- 在 launchd 中,对服务的控制集中在
0.2. 什么是 plist#
- MacOS 用来存储序列化后的对象的文件,文件后缀名为 plist,因为称为 plist 文件。
- 对于 launchd 来说,每一个 plist 文件即为一个任务(Job)
- launchd 启动时,会扫描
/System/Library/LaunchDaemons
和/Library/LaunchDaemons
中的所有 plist 文件并加载它们 - 用户登录后,会扫描
/System/Library/LaunchAgents
、/Library/LaunchAgents
、~/Library/LaunchAgents
这三个目录的文件并加载它们 - plist 中设置了
RunAtLoad
为true
或KeepAlive
为true
时,会在加载时立即执行
- launchd 启动时,会扫描
plist 示例:
1 |
|
0.3. plist 放在不同位置时的区别#
类型 | 位置 | 以什么用户权限运行 | 运行时机 |
---|---|---|---|
系统 Daemons | /System/Library/LaunchDaemons |
root/指定用户 | 开机时 |
全局 Daemons | /Library/LaunchAgents |
root/指定用户 | 开机时 |
系统 Agents | /System/Library/LaunchAgents |
当前登录用户 | 用户登录 |
全局 Agents | /Library/LaunchAgents |
当前登录用户 | 用户登录 |
用户 Agents | ~/Library/LaunchAgents |
当前登录用户 | 当前设置用户登录时 |
LaunchDaemons
和LaunchAgents
主要有以下两个区别:
- 运行时机
LaunchDaemons
在按下开机按钮后,用户还未输入密码时,就已经运行了。LaunchAgents
在用户输入密码后,才开始运行。
- 运行用户
LaunchDaemons
是以 root/其他指定用户运行LaunchAgents
是以当前登录用户的权限运行
1. 通过 Launchctl 为 Mac 设置定时任务#
下面通过实现定时开关 Mac 的 Wi-Fi 来演示具体流程:
1.1. 创建待执行的 shell#
如果有多台 Mac 同步需求,建议将以下 shell 放入自己的 iCloud 目录,没有这个需求的话自行安排,记得存放路径就行
- closeWiFi.sh
1 | !/bin/sh |
- openWiFi.sh
1 | !/bin/sh |
1.2. 创建 plist 并放入所需目录#
- 这两个文件用于执行对应的需求,以下几点需要注意
- 具体放哪个目录的参考plist 放在不同位置时的区别,我的放在
/Library/LaunchAgents
下,这样只要电脑开机,就算未输入密码,plist 文件也会被执行到 Label
标签的值,不能与其他 plist 文件中的Label
标签中的值完全重复ProgramArguments
标签中放入 shell 所在的路径StartCalendarInterval
用于控制在指定的时间执行 shell- 可用
StartCalendarInterval
替换为每隔 N 秒执行一次 shell
- 可用
RunAtLoad
和KeepAlive
为true
时,在 plist 被加载时,会被立即执行一次StandardOutPath
填写脚本运行日志输出的路径StandardErrorPath
填写脚本运行错误日志输出的路径
- 具体放哪个目录的参考plist 放在不同位置时的区别,我的放在
- closewifi.plist (每天晚上 23 点 00 分,执行 closeWiFi.sh)
1 |
|
- openwifi.plist(每天早上 09 点 00 分,执行 openWiFi.sh)
1 |
|
2. 常用 Launchctl 命令#
launchctl list
列出已加载的所有 plist
其中 PID 为-
的表示虽然已加载,但是未启动,PID 为数字的表示已启动并且这个数字就时它的 PIDlaunchctl load
launchctl load /Library/LaunchDaemons/closewifi.plist
手动加载一个 plist 任务launchctl unload
launchctl unload /Library/LaunchDaemons/closewifi.plist
禁用一个 plist 任务launchctl start
启动一个 plist 任务launchctl stop
停止一个 plist 任务
3. 更多高级用法参考#
A launchd Tutorial
launchctl
Daemons and Services Programming Guide
man launchd.plist
本作品系原创,采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可,转载请注明出处。