因业务需求,对 Mac 和 Windows 的计划任务做了了解,Windows 的计划任务表示很简单,这里主要介绍 Mac 上的定时任务。

就笔者的了解而言,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 定时任务

launchctl 通过配置文件指定执行周期和任务,不同于 crontab,launchctl 的最小时间间隔是 1s。

plist 文件存放路径为/Library/LaunchAgents/Library/LaunchDaemons,前者仅当用户登陆后才被执行,后者只要系统启动就会被执行。

支持两种方式配置执行时间:

  • StartInterval: 指定脚本每间隔多长时间(单位:秒)执行一次;

  • StartCalendarInterval: 可以指定脚本在多少分钟、小时、天、星期几、月时间上执行,类似如crontab的中的设置,包含下面的 key:

    Minute <integer>
    The minute on which this job will be run.

    Hour <integer>
    The hour on which this job will be run.

    Day <integer>
    The day on which this job will be run.

    Weekday <integer>
    The weekday on which this job will be run (0 and 7 are Sunday).

    Month <integer>
    The month on which this job will be run.

配置文件

进入到~/Library/LaunchAgents下建一个plist文件com.test.launchctl.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.test.launchctl.plist</string>
<key>ProgramArguments</key>
<array>
<string>/usr/bin/python</string>
<string>/Workspace/test.py</string>
</array>
<key>StartCalendarInterval</key>
<dict>
<key>Minute</key>
<integer>4</integer>
<key>Hour</key>
<integer>13</integer>
</dict>
<key>KeepAlive</key>
<false/>
<key>RunAtLoad</key>
<true/>
<key>StandardOutPath</key>
<string>/tmp/AutoMakeLog.log</string>
<key>StandardErrorPath</key>
<string>/tmp/AutoMakeLog.err</string>
</dict>
</plist>
  • 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

参考