c4rt1y

mac 自动定时执行任务 -- launchctl

0x01 介绍

launchctl: 是一个统一的服务管理框架,可以启动、停止和管理守护进程、应用程序、进程和脚本等。

0x02 使用方法

launchctl 将根据plist文件的信息来启动任务。

plist脚本一般存放在以下目录:
/Library/LaunchDaemons -->只要系统启动了,哪怕用户不登陆系统也会被执行
/Library/LaunchAgents -->当用户登陆系统后才会被执行

~/Library/LaunchAgents 由用户自己定义的任务项
/Library/LaunchAgents 由管理员为用户定义的任务项
/Library/LaunchDaemons 由管理员定义的守护进程任务项
/System/Library/LaunchAgents 由Mac OS X为用户定义的任务项
/System/Library/LaunchDaemons 由Mac OS X定义的守护进程任务项

plist部分参数说明
Label:对应的需要保证全局唯一性;
Program:要运行的程序;
ProgramArguments:命令语句
StartCalendarInterval:运行的时间,单个时间点使用dict,多个时间点使用 array <dict>
StartInterval:指定脚本每间隔多长时间执行一次,与StartCalendarInterval使用其一,单位为秒
StandardInPath、StandardOutPath、StandardErrorPath:标准的输入输出错误文件,这里建议不要使用 .log 作为后缀,会打不开里面的信息。
定时启动任务时,如果涉及到网络,但是电脑处于睡眠状态,是执行不了的,这个时候,可以定时的启动屏幕就好了


launchctl load -w com.test.plist 	加载任务, -w选项会将plist文件中无效的key覆盖掉,建议加上
launchctl unload -w com.test.plist 	删除任务
launchctl list | grep 'test.demo' 	查看任务列表, 使用 grep '任务部分名字' 过滤
launchctl start  com.test.plist 	开始任务
launchctl stop   com.test.plist 	结束任务

0x03 测试

# 1、创建两个文件,记录时间
cat ~/Desktop/shell1.sh
time=$(date "+%Y-%m-%d %H:%M:%S")
echo "$time + shell1" >> ~/Desktop/time1.txt

cat ~/Desktop/shell1.sh
time=$(date "+%Y-%m-%d %H:%M:%S")
echo "$time + shell2" >> ~/Desktop/time2.txt

# 2、对两个文件赋予执行权限
chmod +x ~/Desktop/shell1.sh ~/Desktop/shell2.sh

# 3、通过launchctl 两种设置定时任务的方法
## 通过 StartInterval 时间间隔的形式,来对进行执行操作
cat ~/Library/LaunchAgents/com.testa.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>
    <!-- Label唯一的标识 -->
    <key>Label</key>
    <string>com.testa</string>
    <!-- 指定要运行的脚本 -->
    <key>ProgramArguments</key>
    <array>
        <string>/Users/c4rt1y/Desktop/shell1.sh</string>
    </array>
    <!-- 时间间隔 -->
    <key>StartInterval</key>
    <integer>10</integer>
    <key>StandardOutPath</key>
    <!-- 标准输出文件 -->
    <string>/Users/c4rt1y/Desktop/stdout1</string>
    <!-- 标准错误输出文件,错误日志 -->
    <key>StandardErrorPath</key>
    <string>/Users/c4rt1y/Desktop/error1.txt</string>
</dict>
</plist>

## 通过StartCalendarInterval,取值有Minute、Hour、Weekday(0 and 7 == Sunday)等。指定时间运行,时间必须为固定值,比如下方为每小时1分运行一次
cat ~/Library/LaunchAgents/com.testb.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>
    <!-- Label唯一的标识 -->
    <key>Label</key>
    <string>com.testb</string>
    <!-- 指定要运行的脚本 -->
    <key>ProgramArguments</key>
    <array>
        <string>/Users/c4rt1y/Desktop/shell2.sh</string>
    </array>
    <!-- 指定运行的时间 -->
    <key>StartCalendarInterval</key>
    <dict>
        <key>Minute</key>
        <integer>1</integer>
    </dict>
    <key>StandardOutPath</key>
    <!-- 标准输出文件 -->
    <string>/Users/c4rt1y/Desktop/stdout2</string>
    <!-- 标准错误输出文件,错误日志 -->
    <key>StandardErrorPath</key>
    <string>/Users/c4rt1y/Desktop/error2.txt</string>
</dict>
</plist>

## 设置多个定时任务<dict>分隔,用array作为数组
cat ~/Library/LaunchAgents/com.testb.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>
    <!-- Label唯一的标识 -->
    <key>Label</key>
    <string>com.testb</string>
    <!-- 指定要运行的脚本 -->
    <key>ProgramArguments</key>
    <array>
        <string>/Users/c4rt1y/Desktop/shell2.sh</string>
    </array>
    <!-- 指定运行的时间 -->
    <key>StartCalendarInterval</key>
    <array>
    <dict>
        <key>Minute</key>
        <integer>2</integer>
    </dict>
    <dict>
        <key>Hour</key>
        <integer>8</integer>
        <key>Minute</key>
        <integer>2</integer>
    </dict>
    </array>
    <key>StandardOutPath</key>
    <!-- 标准输出文件 -->
    <string>/Users/c4rt1y/Desktop/stdout2</string>
    <!-- 标准错误输出文件,错误日志 -->
    <key>StandardErrorPath</key>
    <string>/Users/c4rt1y/Desktop/error2.txt</string>
</dict>
</plist>

## 4、判断预发是否正常
plutil  com.testa.plist
plutil  com.testb.plist

## 5、加载 并且运行
launchctl load -w com1.test.plist 
launchctl start -w com1.test.plist 

launchctl load -w com2.test.plist 
launchctl start -w com2.test.plist 

## 6、观察
tail -f ~/Desktop/time1.txt
tail -f ~/Desktop/time2.txt

0x04 资料来源

https://www.jianshu.com/p/44313b350b70  mac 自动定时执行任务
GoTop