Mac中的定时任务利器:launchctl(转载)

/ 0评 / 0

launchctl是一个统一的服务管理框架,可以启动、停止和管理守护进程、应用程序、进程和脚本等。
launchctl是通过配置文件来指定执行周期和任务的。

当然mac也可以像linux系统一样,使用crontab命令来添加定时任务,这里就不赘述.

下面将手把手教你在mac上创建定时任务。(任务目标:每天晚上十点定时执行/Users/demo/helloworld.py的python程序)

1. 创建run.sh脚本

进入 helloworld.py程序所在目录
cd /User/demo
创建run.sh脚本
vi run.sh
添加执行helloworld.py的命令

<span class="hljs-meta">#!/bin/sh
</span>
<span class="hljs-comment"># 记录一下开始时间</span>
<span class="hljs-built_in">echo</span> `date` >> /Users/demo/<span class="hljs-built_in">log</span> &&
<span class="hljs-comment"># 进入helloworld.py程序所在目录</span>
<span class="hljs-built_in">cd</span> /Users/demo &&
<span class="hljs-comment"># 执行python脚本(注意前面要指定python运行环境/usr/bin/python,根据自己的情况改变)</span>
/usr/bin/python helloworld.py
<span class="hljs-comment"># 运行完成</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">'finish'</span> >> /Users/demo/<span class="hljs-built_in">log</span>

:wq保存退出

注意,脚本要改成可执行的权限
chmod 777 run.sh

2. 编写plist文件

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

<span class="php"><span class="hljs-meta"><?</span>xml version=<span class="hljs-string">"1.0"</span> encoding=<span class="hljs-string">"UTF-8"</span><span class="hljs-meta">?></span></span>
<span class="hljs-meta"><!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"></span>
<span class="hljs-tag"><<span class="hljs-name">plist</span> <span class="hljs-attr">version</span>=<span class="hljs-string">"1.0"</span>></span>
<span class="hljs-tag"><<span class="hljs-name">dict</span>></span>
  <span class="hljs-comment"><!-- Label唯一的标识 --></span>
  <span class="hljs-tag"><<span class="hljs-name">key</span>></span>Label<span class="hljs-tag"></<span class="hljs-name">key</span>></span>
  <span class="hljs-tag"><<span class="hljs-name">string</span>></span>com.demo.plist<span class="hljs-tag"></<span class="hljs-name">string</span>></span>
  <span class="hljs-comment"><!-- 指定要运行的脚本 --></span>
  <span class="hljs-tag"><<span class="hljs-name">key</span>></span>ProgramArguments<span class="hljs-tag"></<span class="hljs-name">key</span>></span>
  <span class="hljs-tag"><<span class="hljs-name">array</span>></span>
    <span class="hljs-tag"><<span class="hljs-name">string</span>></span>/Users/demo/run.sh<span class="hljs-tag"></<span class="hljs-name">string</span>></span>
  <span class="hljs-tag"></<span class="hljs-name">array</span>></span>
  <span class="hljs-comment"><!-- 指定要运行的时间 --></span>
  <span class="hljs-tag"><<span class="hljs-name">key</span>></span>StartCalendarInterval<span class="hljs-tag"></<span class="hljs-name">key</span>></span>
  <span class="hljs-tag"><<span class="hljs-name">dict</span>></span>
        <span class="hljs-tag"><<span class="hljs-name">key</span>></span>Minute<span class="hljs-tag"></<span class="hljs-name">key</span>></span>
        <span class="hljs-tag"><<span class="hljs-name">integer</span>></span>00<span class="hljs-tag"></<span class="hljs-name">integer</span>></span>
        <span class="hljs-tag"><<span class="hljs-name">key</span>></span>Hour<span class="hljs-tag"></<span class="hljs-name">key</span>></span>
        <span class="hljs-tag"><<span class="hljs-name">integer</span>></span>22<span class="hljs-tag"></<span class="hljs-name">integer</span>></span>
  <span class="hljs-tag"></<span class="hljs-name">dict</span>></span>
<span class="hljs-comment"><!-- 标准输出文件 --></span>
<span class="hljs-tag"><<span class="hljs-name">key</span>></span>StandardOutPath<span class="hljs-tag"></<span class="hljs-name">key</span>></span>
<span class="hljs-tag"><<span class="hljs-name">string</span>></span>/Users/demo/run.log<span class="hljs-tag"></<span class="hljs-name">string</span>></span>
<span class="hljs-comment"><!-- 标准错误输出文件,错误日志 --></span>
<span class="hljs-tag"><<span class="hljs-name">key</span>></span>StandardErrorPath<span class="hljs-tag"></<span class="hljs-name">key</span>></span>
<span class="hljs-tag"><<span class="hljs-name">string</span>></span>/Users/demo/run.err<span class="hljs-tag"></<span class="hljs-name">string</span>></span>
<span class="hljs-tag"></<span class="hljs-name">dict</span>></span>
<span class="hljs-tag"></<span class="hljs-name">plist</span>></span>

3. 加载命令

launchctl load -w com.demo.plist
这样任务就加载成功了。

更多的命令:

<span class="hljs-comment"># 加载任务, -w选项会将plist文件中无效的key覆盖掉,建议加上</span>
$ launchctl load -w com.demo.plist

<span class="hljs-comment"># 删除任务</span>
$ launchctl unload -w com.demo.plist

<span class="hljs-comment"># 查看任务列表, 使用 grep '任务部分名字' 过滤</span>
$ launchctl <span class="hljs-keyword">list</span> | grep <span class="hljs-string">'com.demo'</span>

<span class="hljs-comment"># 开始任务</span>
$ launchctl start  com.demo.plist

<span class="hljs-comment"># 结束任务</span>
$ launchctl stop   com.demo.plist

如果任务呗修改了,那么必须先unload,然后重新load
start可以测试任务,这个是立即执行,不管时间到了没有
执行start和unload前,任务必须先load过,否则报错
stop可以停止任务

番外篇

plist支持两种方式配置执行时间:
  • StartInterval: 指定脚本每间隔多长时间(单位:秒)执行一次;
  • StartCalendarInterval: 可以指定脚本在多少分钟、小时、天、星期几、月时间上执行,类似如crontab的中的设置,包含下面的 key:
Minute <<span class="hljs-built_in">integer</span>>
The minute on <span class="hljs-built_in">which</span> this job will be run.
Hour <<span class="hljs-built_in">integer</span>>
The hour on <span class="hljs-built_in">which</span> this job will be run.
Day <<span class="hljs-built_in">integer</span>>
The day on <span class="hljs-built_in">which</span> this job will be run.
Weekday <<span class="hljs-built_in">integer</span>>
The weekday on <span class="hljs-built_in">which</span> this job will be run (0 and 7 are Sunday).
Month <<span class="hljs-built_in">integer</span>>
The month on <span class="hljs-built_in">which</span> this job will be run.
plist部分参数说明:
  1. Label:对应的需要保证全局唯一性;
  2. Program:要运行的程序;
  3. ProgramArguments:命令语句
  4. StartCalendarInterval:运行的时间,单个时间点使用dict,多个时间点使用 array <dict>
  5. StartInterval:时间间隔,与StartCalendarInterval使用其一,单位为秒
  6. StandardInPath、StandardOutPath、StandardErrorPath:标准的输入输出错误文件,这里建议不要使用 .log 作为后缀,会打不开里面的信息。
  7. 定时启动任务时,如果涉及到网络,但是电脑处于睡眠状态,是执行不了的,这个时候,可以定时的启动屏幕就好了。

发表评论

邮箱地址不会被公开。 必填项已用*标注