Mac 有两种方式可以添加定时任务:
crontab 命令launchctl 定时任务 crontab 命令
通过crontab 命令,我们可以在固定的间隔时间执行指定的系统指令或 shell script脚本。时间间隔的单位可以是分钟、小时、日、月、周及以上的任意组合。这个命令非常适合周期性的日志分析或数据备份等工作。
命令格式
crontab [-u user] file crontab [-u user] [ -e | -l | -r ]
-u user:用来设定某个用户的crontab服务;file:file是命令文件的名字,表示将file做为crontab的任务列表文件并载入crontab。如果在命令行中没有指定这个文件,crontab命令将接受标准输入(键盘)上键入的命令,并将它们载入crontab。-e:编辑某个用户的crontab文件内容。如果不指定用户,则表示编辑当前用户的crontab文件。-l:显示某个用户的crontab文件内容,如果不指定用户,则表示显示当前用户的crontab文件内容。-r:从/var/spool/cron目录中删除某个用户的crontab文件,如果不指定用户,则默认删除当前用户的crontab文件。-i:在删除用户的crontab文件时给确认提示。
crontab 文件格式
分 时 日 月 星期 要运行的命令
第1列分钟1~59第2列小时1~23(0表示子夜)第3列日1~31第4列月1~12第5列星期0~7(0和7表示星期天)第6列要运行的命令 备份/恢复 crontab
可以定时备份 crontab 以防误删操作
# 备份 crontab -l > $HOME/.mycron # 恢复 crontab $HOME/.mycron定时实例
# 每1分钟执行一次myCommand * * * * * myCommand # 每小时的第3和第15分钟执行 3,15 * * * * myCommand # 在上午8点到11点的第3和第15分钟执行 3,15 8-11 * * * myCommand # 每隔两天的上午8点到11点的第3和第15分钟执行 3,15 8-11 */2 * * myCommand # 每周一上午8点到11点的第3和第15分钟执行 3,15 8-11 * * 1 myCommand # 晚上11点到早上7点之间,每隔一小时重启smb * 23-7/1 * * * /etc/init.d/smb restart
注意清理系统用户的邮件日志
每条任务调度执行完毕,系统都会将任务输出信息通过电子邮件的形式发送给当前系统用户,这样日积月累,日志信息会非常大,可能会影响系统的正常运行,因此,将每条任务进行重定向处理非常重要。 例如,可以在crontab文件中设置如下形式,忽略日志输出:
0 */3 * * * /usr/local/apache2/apachectl restart >/dev/null 2>&1
launchctl 定时任务
下面将手把手教你在mac上创建定时任务。(任务目标:每天晚上十点定时执行/Users/demo/helloworld.py的python程序)
1. 创建run.sh脚本进入 helloworld.py程序所在目录
cd /User/demo
创建run.sh脚本
vi run.sh
添加执行helloworld.py的命令
#!/bin/sh # 记录一下开始时间 echo `date` >> /Users/demo/log && # 进入helloworld.py程序所在目录 cd /Users/demo && # 执行python脚本(注意前面要指定python运行环境/usr/bin/python,根据自己的情况改变) /usr/bin/python helloworld.py # 运行完成 echo 'finish' >> /Users/demo/log
:wq保存退出
注意,脚本要改成可执行的权限
chmod 777 run.sh
launchctl 将根据plist文件的信息来启动任务。
plist脚本一般存放在以下目录:
/Library/LaunchDaemons -->只要系统启动了,哪怕用户不登陆系统也会被执行
/Library/LaunchAgents -->当用户登陆系统后才会被执行
更多的plist存放目录:
~/Library/LaunchAgents :由用户自己定义的任务项 /Library/LaunchAgents :由管理员为用户定义的任务项 /Library/LaunchDaemons :由管理员定义的守护进程任务项 /System/Library/LaunchAgents :由Mac OS X为用户定义的任务项 /System/Library/LaunchDaemons :由Mac OS X定义的守护进程任务项
进入~/Library/LaunchAgents,创建一个plist文件com.demo.plist
Label com.demo.plist ProgramArguments /Users/demo/run.sh StartCalendarInterval Minute 00 Hour 22 StandardOutPath /Users/demo/run.log StandardErrorPath /Users/demo/run.err
launchctl 通过配置文件指定执行周期和任务,不同于 crontab,launchctl 的最小时间间隔是 1s。
plist 文件存放路径为/Library/LaunchAgents或/Library/LaunchDaemons,前者仅当用户登陆后才被执行,后者只要系统启动就会被执行。
支持两种方式配置执行时间:
StartInterval: 指定脚本每间隔多长时间(单位:秒)执行一次;
StartCalendarInterval: 可以指定脚本在多少分钟、小时、天、星期几、月时间上执行,类似如crontab的中的设置,包含下面的 key:
MinuteThe minute on which this job will be run. Hour The hour on which this job will be run. Day The day on which this job will be run. Weekday The weekday on which this job will be run (0 and 7 are Sunday). Month The month on which this job will be run.
3. 加载命令
launchctl load -w com.demo.plist
这样任务就加载成功了。
# 加载任务, -w选项会将plist文件中无效的key覆盖掉,建议加上 $ launchctl load -w com.demo.plist # 删除任务 $ launchctl unload -w com.demo.plist # 查看任务列表, 使用 grep '任务部分名字' 过滤 $ launchctl list | grep 'com.demo' # 开始任务 $ launchctl start com.demo.plist # 结束任务 $ launchctl stop com.demo.plistplist 文件的字段说明
Label com.uniflor.notifier Program /Users/uniflor/script.sh ProgramArguments /Users/uniflor/script.sh StartCalendarInterval Minute 30 Hour 9 Day 1 Month 5 Weekday 0 StartInterval 30 StandardInPath /Users/uniflor/run-in.log StandardOutPath /Users/uniflor/Bin/run-out.log StandardErrorPath /Users/uniflor/Bin/run-err.log
配置文件
进入到~/Library/LaunchAgents下建一个plist文件com.test.launchctl.plist,内容如下:
Label com.test.launchctl.plist ProgramArguments /usr/bin/python /Workspace/test.py StartCalendarInterval Minute 4 Hour 13 KeepAlive RunAtLoad StandardOutPath /tmp/AutoMakeLog.log StandardErrorPath /tmp/AutoMakeLog.err
StartCalendarInterval: 执行周期RunAtLoad: 加载时执行一次StandardOutPath: 标准输出路径StandardErrorPath: 错误输出路径 管理定时任务
加载任务
cd ~/Library/LaunchAgents launchctl load com.test.launchctl.plist
卸载任务
launchctl unload com.felink.gitmirror.plist
立即执行一次任务
launchctl start ccom.test.launchctl.plist
停止任务
launchctl stop ccom.test.launchctl.plist
写个简单的applescript。
on callmeican()
set meican_url to "https://meican.com" as string
tell application "Google Chrome"
open location meican_url
activate
end tell
end callmeican
say "不要这么拼了,预订美餐时间到了"
display dialog "不要这么拼了,预订美餐时间到了(截至时间16:30)!" buttons {"好的", "我不定了"} default button 1
if the button returned of the result is "好的" then
-- action for 1st button goes here
callmeican()
end if
脚本的作用大概是MAC会通过弹窗和语音提醒我该订餐了,如果选择定,就自动用浏览器打开订餐的页面。这个脚本每天在四点执行。
1、使用crontab设置定时任务
crontab -e 或者sudo crontab -e。 00 16 * * * osascript /Users/hanlingzhi/project/applescript/meican.scpt
输入完成后,保存退出。系统自动建立新cron,提示如下:crontab: installing new crontab。设置非常简单。
2、使用苹果的Schedule jobs using launchd设置定时任务。需要写一个plist文件,描述任务的动作、间隔的时间、日志输出等参数。
我创建一个plist文件com.hanlingzhi.cron.meican.plist,大概内容如下:
Label com.hanlingzhi.cron.meican ProgramArguments osascript /Users/hanlingzhi/project/applescript/meican.scpt StartCalendarInterval Minute 0 Hour 16 StandardInPath /Users/hanlingzhi/project/applescript/log/run-in-meican.log StandardOutPath /Users/hanlingzhi/project/applescript/log/run-out-meican.log StandardErrorPath /Users/hanlingzhi/project/applescript/log/run-err-meican.log
然后将plist文件放在/Users/hanlingzhi/Library/LaunchAgents,你的用户目录下,然后执行launchctl load plist就可以启动了。
plist脚本存放路径为/Library/LaunchDaemons或用户目录/Library/LaunchAgents,其区别是后一个路径的脚本当用户登陆系统后才会被执行,前一个只要系统启动了,哪怕用户不登陆系统也会被执行。
可以通过两种方式来设置脚本的执行时间。一个是使用StartInterval,它指定脚本每间隔多长时间(单位:秒)执行一次;另外一个使用StartCalendarInterval,它可以指定脚本在多少分钟、小时、天、星期几、月时间上执行,类似如crontab的中的设置。
StartInterval 3600 或者StartCalendarInterval Minute 30 Hour 9
launchctl的命令使用大家看一下帮助文档。
由于操作还是比较复杂,为了帮助快速执行,写了个shell快速拷贝新的plist并完成服务重启
__path='/Users/hanlingzhi/project/applescript'
__plist_path=${__path}/plist
__launchagents_path='/Users/hanlingzhi/Library/LaunchAgents'
# 拷贝plist到用户自己定义的任务项目录
cp -rf ${__plist_path}/* ${__launchagents_path}
# 根据plist中的文件遍历load
for plist_file in `ls ${__plist_path}`
do
echo "重启${plist_file}定时任务"
launchctl unload ${__launchagents_path}/${plist_file}
sleep 0.5
launchctl load ${__launchagents_path}/${plist_file}
task_name=`echo ${plist_file} | sed 's/.plist//g'`
launchctl list | grep ${task_name}
done
总结一下
虽然plist的设置会复杂很多。但是当前在mac os还是倾向于推荐使用Plist的方法,crontab已不推荐使用。
两者的区别:
1、plist可以设置到秒,而crontab只能到分钟。
2、plist可以同时应用于Mac OS/Iphone。
3、plist对于MAC上系统交互的操作更支持(我就出现过用crontab设置,运行时出现execution error: 不允许用户交互。 (-1713)的错误
更多关于launchctl的介绍可以查看官方介绍:Creating Launch Daemons and Agents
原文「林中静月下仙」的原创文章链接:https://blog.csdn.net/qq_21137441/article/details/106608115



