惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

C
CXSECURITY Database RSS Feed - CXSecurity.com
K
Kaspersky official blog
A
Arctic Wolf
Attack and Defense Labs
Attack and Defense Labs
L
LINUX DO - 热门话题
N
News | PayPal Newsroom
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
L
Lohrmann on Cybersecurity
PCI Perspectives
PCI Perspectives
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
The Last Watchdog
The Last Watchdog
B
Blog RSS Feed
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
W
WeLiveSecurity
Know Your Adversary
Know Your Adversary
博客园 - Franky
T
Tenable Blog
T
Tailwind CSS Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Help Net Security
Help Net Security
WordPress大学
WordPress大学
T
The Exploit Database - CXSecurity.com
www.infosecurity-magazine.com
www.infosecurity-magazine.com
博客园 - 司徒正美
阮一峰的网络日志
阮一峰的网络日志
D
Darknet – Hacking Tools, Hacker News & Cyber Security
H
Heimdal Security Blog
TaoSecurity Blog
TaoSecurity Blog
S
Security Affairs
J
Java Code Geeks
小众软件
小众软件
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Apple Machine Learning Research
Apple Machine Learning Research
NISL@THU
NISL@THU
O
OpenAI News
The Cloudflare Blog
月光博客
月光博客
Google Online Security Blog
Google Online Security Blog
V
V2EX
罗磊的独立博客
美团技术团队
博客园 - 三生石上(FineUI控件)
Security Latest
Security Latest
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
C
Cyber Attacks, Cyber Crime and Cyber Security
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Cyberwarzone
Cyberwarzone
L
LINUX DO - 最新话题
Hacker News - Newest:
Hacker News - Newest: "LLM"
大猫的无限游戏
大猫的无限游戏

吴润写字的地方

从零构建 A 股 ETF 动量轮动系统:一个量化新手的完整指南 2025 年 8 月 Digest 2025 年 7 月 Digest 2025 年 6 月 Digest 2025 年 5 月 Digest 2025 年 4 月 Digest 清明桐庐行 2025 年 3 月 Digest 2024 年终总结 换车 崇明岛一日游 夜游徐汇滨江绿地 2023 年终总结 踏春之浦康休闲公园 香港澳门行 读「投资第一课」有感 皮皮玩球 Chrome 插件推荐 Go 并发之道:并发介绍 The Night Agent 我是如何使用 ChatGPT 的 2022 年终总结 在 Ubuntu 上搭建 MinIO 2021 年终总结 Golang 不可寻址的理解 Golang 的 defer 关键字使用注意事项 恭王府 强制删除 k8s terminating 状态命名空间 PromQL 计算 CPU 使用率 PromQL 如何计算变化(率) Trickster 使用 奥森的向日葵 Go Modules - checksum mismatch 错误解决 CDN 使用初探 k8s 介绍 再探 798 解决 gin 路由冲突问题 wu.run 域名正式使用 GoLand 使用指南 macOS 软件推荐 2020 这一年 Python 循环列表删除元素的注意事项 Linux 服务器搭建 VNC 可视化桌面 Jenkins 个别 job 页面打开超时的解决方法 遇见 Aamir Khan Hexo 从 GitHub 到阿里云 『从未说出口的秘密』词云分析 768 的秋天 北戴河 Outing 飞盘记 三里屯夜景 爬虫图解:轮子哥关注了哪些人 2017-06-30 GitHub+Hexo 搭建个人网站详细教程 特朗普税改 如果有一天,苹果和微信只能选一个,你会选哪一个? About | 吴润写字的地方 Links | 吴润写字的地方 Memos | 吴润写字的地方
Mac 下的定时任务工具:Launchctl
2019-03-27 · via 吴润写字的地方

Launchctl 是 Mac 系统自带的定时任务工具,与 crontab 功能类似。

Launchctl 的使用

以简单的例子展示如何使用 Launchctl,比如现有一个位于 /Users/rundouble/Desktop 目录的 run.sh 脚本,脚本内容如下:

并执行 chmod a+x run.sh 获取执行权限。

期望每 30 秒钟以定时任务运行上面的脚本。

首先,切换到管理员权限:

进入 /Library/LaunchDaemons 目录下:

cd /Library/LaunchDaemons

创建 com.iamwr.launchctl.demo.agent.plist 定时任务描述文件:

vim com.iamwr.launchctl.demo.agent.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.iamwr.launchctl.demo.agent</string>
    <key>Program</key>
    <string>/Users/rundouble/Desktop/run.sh</string>
    <key>ProgramArguments</key>
    <array>
        <string>/Users/rundouble/Desktop/run.sh</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>StartInterval</key>
    <integer>30</integer>
    <key>StandardOutPath</key>
    <string>/Users/rundouble/Desktop/run.log</string>
    <key>StandardErrorPath</key>
    <string>/Users/rundouble/Desktop/run.err</string>
</dict>
</plist>

.plist 文件标签说明:

  • Label:定时任务的名称,这里 Label 的值是 com.iamwr.launchctl.demo.agent,要全局唯一,可通过:launchctl list 查看已有的定时任务

  • Program:是要运行的脚本的名称,这里是 /Users/rundouble/Desktop/run.sh

  • ProgramArguments: 脚本运行的参数,第一个是运行的命令,其余是运行需要的参数,这里是 /Users/rundouble/Desktop/run.sh,由于运行这个脚本不需要其他参数,所有只有这一个命令

  • RunAtLoad:表示加载定时任务即开始执行脚本

  • StartInterval: 定时任务的周期,单位为秒,这里 30 代表每 30s 执行一次脚本

  • StandardOutPath: 标准输出日志的路径

  • StandardErrorPath: 标准错误输出日志的路径

加载该定时任务:

launchctl load -w com.iamwr.launchctl.demo.agent.plist

-w 参数会将 .plist 文件中无意义的键值过滤掉,建议加上。

这时,定时任务已加载,由于加上了:

<key>RunAtLoad</key>
    <true/>

所以该定时任务成功加载后就开始执行,可以在 /Users/demo/run.log 看到每 30s 打印当前时间:

如果我们的目标不是每 30 秒执行脚本,而是每天固定时间执行脚本,比如每天晚上 22:00 执行脚本,那么我们需要对 .plist 文件进行如下修改:

  • 删除:
<key>StartInterval</key>
    <integer>30</integer>
  • 添加:
<key>StartCalendarInterval</key>
    <dict>
        <key>Hour</key>
        <integer>22</integer>
        <key>Minute</key>
        <integer>0</integer>
    </dict>

新的 .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.iamwr.launchctl.demo.agent</string>
    <key>Program</key>
    <string>/Users/rundouble/Desktop/run.sh</string>
    <key>ProgramArguments</key>
    <array>
        <string>/Users/rundouble/Desktop/run.sh</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>StartCalendarInterval</key>
    <dict>
        <key>Hour</key>
        <integer>22</integer>
        <key>Minute</key>
        <integer>0</integer>
    </dict>
    <key>StandardOutPath</key>
    <string>/Users/rundouble/Desktop/run.log</string>
    <key>StandardErrorPath</key>
    <string>/Users/rundouble/Desktop/run.err</string>
</dict>
</plist>

StartInterval 标签代表每多少秒执行,StartCalendarInterval 标签代表指定时间点执行,所以这两个标签在同一个 .plist 文件中只能存在一个。StartCalendarInterval 的 key 有:

Key Type Values
Month Integer Month of year (1..12, 1 being January)
Day Integer Day of month (1..31)
Weekday Integer Day of week (0..7, 0 and 7 being Sunday)
Hour Integer Hour of day (0..23)
Minute Integer Minute of hour (0..59)

同样使用 launchctl load -w com.iamwr.launchctl.demo.agent.plist 命令可使新的定时任务运行起来,在每天 22:00 时运行。

Launchctl 细节

.plist 文件存放位置

上述展示中,.plist 描述文件是存放在 /Library/LaunchDaemons 目录下,除了这个目录还可以存在其他位置:

Type Location Run on behalf of
User Agents ~/Library/LaunchAgents Currently logged in user
Global Agents /Library/LaunchAgents Currently logged in user
Global Daemons /Library/LaunchDaemons root or the user specified with the key UserName
System Agents /System/Library/LaunchAgents Currently logged in user
System Daemons /System/Library/LaunchDaemons root or the user specified with the key UserName

存放 在 LaunchAgents 代表用户登录后启动任务;存放在 LaunchDaemons 代表用户登录前就启动任务。一般将自定义的 .plist 存放在 /Library/LaunchDaemons 目录下。

Launchctl 相关命令

查看已有的任务:

查看指定的任务 xxx 是否存在(加载):

launchctl list | grep xxx

加载指定的任务 xxx:

删除任务:

launchctl unload -w xxx

launchctl load xxx

开始任务:

停止任务:

注意:

  • 如果任务修改了,必须先 unload,然后重新执行 load

  • start 可以测试任务,这个命令是立即执行,不管时间到了没有

  • 执行 start 和 unload 命令前,任务必须先执行过 load,否则报错

  • .plist 中不要添加 KeepAlive 标签,否则无条件 10s 定时执行

参考