我们经常有这样的需求,发现磁盘空间快满了要去手动
清一下,clone完自己star的项目后,隔一段时间会去手动
pull一下代码,这样的操作虽然可行,但无形之中浪费了我们很多时间,有没一种方式能自动定时地帮你去清空间,自动帮你去pull一下你喜欢的项目的代码呢,今天就给大家介绍一下mac自动定时执行任务的神器,launchRocket
不过在介绍此神器之前我们还要先了解一些概念性的东西
在linux/unix下,我们通常用crontab来定时执行我们的任务,什么是crontab
crontab 是一个可以用来根据时间、日期、月份、星期的组合来调度对重复任务的执行的守护进程。
不过在Mac上,自从10.4(也就是Tiger)起,crontab已经被deprecated了,因为Apple推出了一款更强大的工具launchd
a unified, open-source service management framework for starting, stopping and managing daemons, applications, processes, and scripts. Written and designed by Dave Zarzycki at Apple, it was introduced with Mac OS X Tiger and is licensed under the Apache License.
它吸收了crontab的优点,且更加灵活,更加强大,它除了可以定时执行某些任务,也可以基于某些事件来触发任务,比如当监听到网络连接,或者当观察某个文件被移到某个文件夹,都可以触发我们指定的任务,甚至当执行的任务crash掉了,launchtl能做到让它重新运行!最大的区别是在系统即将sleep或shutdown的情况下,如果此时schedule的任务刚好要执行,两者对它的处理方式的不同,crontab只是简单的不运行此调度任务,但launchd会注意到此任务被终止了,将会在适当的时机再次重启此任务!
launchd有两种形式: launchDaemons和launchAgents,这两种形式有何区别呢?主要区别在于agent代表的是当前已登录的用户执行的任务,而daemon代表的是root用户或者任何你用UserName
这个key(这个key在下文所说的plist文件里指定)指定的用户的任务
好了,现在我们已经知道了launchd的功能了,那么我们该如何为其指定一个任务来让其定时执行呢?实际上launchd的每一个任务(job)都对应了一个plist文件(以xml的格式), 它被launchd视为daemon还是agent就看我们把它放在以下哪个目录下了
类型 | 位置 | 代表谁执行 |
---|---|---|
用户代理(User Agents) | ~/Library/LaunchAgents | 当前登录的用户 |
全局代理(Global Agents) | /Library/LaunchAgents | 当前登录的用户 |
全局守护进程(Global Daemons) | /Library/LaunchDaemons | root或者在plist里指定UserName此key对应的用户 |
系统代理(System Agents) | /System/Library/LaunchAgents | 当前登录的用户 |
系统守护进程(System Daemons) | /System/Library/LaunchDaemons | root或者在plist里指定UserName此key对应的用户 |
从上图可知,我们可以将plist文件放在LaunchAgents或LaunchDaemons目录下,都可以定时执行plist里指定的任务,需要注意
的是,我们不应该把第三方的任务放在/System/Library
上,这个目录下存放着对于操作系统所需要的极其重要的任务!应该把第三方任务放在/Library
的LaunchAgents或LaunchDaemons目录下!
plist文件格式
好了,前面既然说了job是用一个plist文件来指定的,那我们来看下这个plist文件的格式是咋样的,来看一个demo
<?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.hello</string>
<key>ProgramArguments</key>
<array>
<string>/Users/ronaldo/test.sh</string>
</array>
<key>Nice</key>
<integer>1</integer>
<key>StartInterval</key>
<integer>60</integer>
<key>RunAtLoad</key>
<true/>
<key>StandardErrorPath</key>
<string>/tmp/AlTest1.err</string>
<key>StandardOutPath</key>
<string>/tmp/AlTest1.out</string>
</dict>
</plist>
我们来一步步解释这些key
当然以上选项只是选择了几个选项进行说明而已,实际上还有更多的选项可以设定,比如我们还可以指定脚本在每一天的某一时刻执行等等,请自行查阅相关文档
好了,现在我们已经知道如何定义一个job了,然后你可以把这些写好的job的plist文件丢到launchAgent或laucnDaemon目录里了,当然了,还有一种选择,想必聪明的你已经想到了,那就是我们今天要介绍的主角LaunchRocket!
将写好的plist丢到相应的Agent或Daemon目录里来执行固定可以,但不够直观,LaunchRocket就为我们提供了一个直观的图形界面,如下
我们可以清楚的看到,哪一个任务在跑,是否以Root身份执行,是否一登录就执行,我们可以根据脚本的运行情况来决定是否将这两个选项勾选上,一切尽在掌握!
我们写好plist文件之后只需要点击Add .plist
就可将任务添加进来,是不是很方便!
接下来我们就做一个任务,定时更新hosts文件。
首先请根据LaunchRocket官网的提示自行安装它
由于GFW的原因,要访问google,我们可以采取两种方式,一种是用V**,另一种绑定Google的hosts,github上已经有项目为我们提供了此hosts,可以点击 这里 查看,这个hosts项目会定时更新,隔几天会更新一次,如果我们手动clone再copy到/etc/hosts明显浪费时间,这个时候我们就可以用LaunchRocket了
我们先来写将此项目的hosts copy到/et/hosts的脚本,非常简单,如下
//hosts_update.sh#!/bin/sh
cd /Users/ronaldo/Documents/husor/hosts;
git pull;
sudo cp hosts /etc/hosts;
注意
:由于我已经将hosts clone到本地了,所以这里我用的方法进入到hosts目录下然后git pull
的方式更新 我们将此脚本命名为hosts_update.sh
,接下来该写我们的plist文件,我们指定每隔一小时更新一下/etc/hosts文件,对应的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.ronaldo.host</string>
<key>ProgramArguments</key>
<array>
<string>/Users/ronaldo/hosts_update.sh</string>
</array>
<key>Nice</key>
<integer>1</integer>
<key>StartInterval</key>
<integer>60</integer>
<key>RunAtLoad</key>
<true/>
<key>StandardErrorPath</key>
<string>/tmp/AlTest1.err</string>
<key>StandardOutPath</key>
<string>/tmp/AlTest1.out</string>
</dict>
</plist>
接下来我们只要手指一点,将此plist添加到LaunchRocket即可,需要注意的是,将文件copy到/etc/hosts需要管理员权限,所以我们勾上As Root
这个选项即可,同时我们也需要在登录的时候也执行一下此脚本,所以也勾上At Login
,这样此脚本每隔一小时就能自动执行了
妈妈再也不用担心我的访问外国网站了!