注意:进公司和有公司成员离职,一定要问计划任务,防止别人搞破坏背锅
13.1 一次性计划任务(atd服务)
1 安装 atd 服务
yum install -y at
systemctl enable atd
systemctl start atd ## 启动atd服务
systemctl status atd ## 查看atd服务状态,有没有启动等等
注意: Start restart stop enable (设置开机自启动) disable(移出开启自启动队列)status(查看状态)
2 at 命令
at 功能:在一个指定的时间执行一个指定任务,只能执行一次
语法: at [命令选项] 时间格式
at 命令系列:at、batch、atq、atrm
命令选项:
-V ## 显示<版本号>
-q queue ## 使用<指定的 queue 队列>## <queue 队列>的<名称>是<单个字母>,取自范围是:a~zA~Z## <a 队列>是at的<默认队列>## <b 队列>是batch的<默认队列>## <更高字母的 queue 队列>的<运行时 nice 值>就更高## "="特殊队列:保留用于<当前正在运行的作业>
-m ## 在<作业>完成之后,向<用户>发送<邮件>
-M ## 不向<用户>发送<邮件>
-f file ## 从<指定文件>读取<job 作业>,指定 要运行的脚本文件
-t time ## 设置:<job作业>的<运行时间>,<时间格式>为:[[CC]YY]MMDDhhmm[.ss]
-l ## 和 atq 一样,查看计划任务,重要
-r ## 这是atrm的一个<别名> 删除计划任务 比如at -r 3
-d ## 这是atrm的一个<别名>
-b ## 这是batch的一个<别名>,batch:类似于 at 命令,但用于在系统负载较低的时候批量执行任务。
batch 命令与 at 命令类似,但在系统空闲时才执行,而不是在特定时间点上执行。
-v ## 显示:在<读取作业>之前,<作业>的<执行时间>## 显示的时间格式将采用<"Thu Feb 20 145000 1997">格式
-c n ## 显示:<指定 job 作业标识符>的<jobs 作业内容>
3 at 一次性计划任务的时间描述法
示例说明理解:
● [HH:MM]
例如:
at 04:00 ## 在今日的<HH:MM时刻>进行,假如时间已过,则在明天的<HH:MM时刻>进行。● HH:MM YYYY-MM-DD
例如:
at 04:00 2009-03-17 ## 在<某年某月的某一天的某一时刻>进行<该项任务>● HH:MM[am|pm] [Month] [Date]
例如:
at 04pm March 17 ## 在<某年某月的某一天的某一时刻>进行<该项任务> 难记少用HH:MM[am|pm] + number [minutes|hours|days|weeks]
例如:
at now + 5 minutes ## 在<某一个时间点>再加<几个时间>之后,才进行<该项任务>
at 04pm + 3 days ## 在<某一个时间点>再加<几个时间>之后,才进行<该项任务>
4 制定 at 计划任务
1 直接制定计划任务
格式:
at [执行时间] ## 回车
输入要执行的内容 ## 写错时候,按住Ctrl + 删除键 才可以删除输入的内容,Enter是到下一行,可写要执行的第二个内容,写完 Ctrl + D 完成
例如 以下是终端显示
[root@dj tmp]# at now + 1minutes
at> mkdir /tmp/aa
at> touch /tmp/bb.txt<EOT> ## 这里写完 bb.txt ctrl+D 即可
job 9 at Thu Jul 27 12:51:00 2023## 可使用atq或者at -l查看有无计划任务,到时间了ls查看aa和bb.txt是否生成
2 执行脚本文件的计划任务
vim /tmp/test.sh ## 创建一个脚本,计划任务运行该脚本
内容如下#!/bin/bash ## 必须有该行,不然没有运行环境
touch /tmp/1.txt ## wq 保存退出at -f /tmp/test.sh 00:00 ## 在00:00执行该脚本内容,创建1.txt
at -f /tmp/test.sh now + 90 minutes ## 在90分钟后创建1.txt文件
at -f /tmp/test.sh 20:00 2024-06-24 ## 在2024.6.24晚上8点创建该文件
5 查看当前用户待处理的 job 作业(计划任务)
注意:如果<当前用户>是root,则可列出:<所有用户>的<待处理 job 作业>
atq 或者 at -l
6 删除计划任务
注意:如果<当前用户>是root,则可删除:<所有用户>的<待处理 job 作业>
atrm 1 2 3 4 ## 数字是每个计划任务的编号,atq查看都有编号
at -r 1 2 3 4
7 管理at计划任务的制定权限
(1) 首先:读取</etc/at.allow文件>,检查<该用户>是否被<明确允许>
</etc/at.allow文件>优先级最高,最严厉:默认拒绝一切,除非<明确允许>
对<root 用户>无效
</etc/at.allow文件>默认未创建,需手动创建
通俗来说就是白名单,在名单里面的用户都可以制定at计划任务,不在就不行
(2) 其次:读取</etc/at.deny文件>,检查<该用户>是否被<明确拒绝>
</etc/at.deny文件>优先级最低,最宽松:默认允许一切,除非<明确拒绝>
对<root 用户>无效
</etc/at.frny文件>默认创建,所有一般有黑名单,没有白名单,如果有白名单的话,不在白名单里面都不能制定 at 计划任务
(3) 最后:如果</etc/at.allow 和 /etc/at.deny>均不存在,则仅允许<root 用户>制定<at 一次性 计划任务>
通俗来说就是黑名单,在名单里面的用户都可以禁止制定at计划任务
注意:如果黑名单白名单都有该用户,则可以制定,因为白名单优先级比较高
如果都没有该用户,但是白名单文件存在,则除了白名单填写的用户,黑名单和正常用户都不可制定 at 计划用户
如果都没有该用户,且白名单并未创建,只要不在黑名单的用户都可以制定 at 计划任务
例子:
1 黑名单 明确拒绝<user01 和 user02>
vi /etc/at.deny ## 一行仅写一个<用户帐号>
user01
user02
2 白名单 拒绝一切,明确允许<user01 和 user02>
vi /etc/at.allow ## 一行仅写一个<用户帐号>
user01
user02
13.2 周期性计划任务(crond服务)
1 安装 crond 服务
安装 crond 默认已安装
yum install -y crontabs
相关管理 crond 服务启动脚本
systemctl enable crond ## 设置:开机自启动
systemctl start crond ## 启动
systemctl status crond ## 查看状态
systemctl reload crond ## 重载
systemctl restart crond ## 重启
systemctl stop crond ## 停止
2 crond 周期性 计划任务 语法格式
重点: /etc/crontab 从该文件里面看格式,和制定相关计划任务
输入 crontab -e 进去的文件也可进行制定计划任务 ,而且可以通过 crontab -l 查看该文件配置的计划任务(该配置文件内容)
vim /etc/crontab ## 可从该文件里面制定周期性计划任务
显示如下:SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root# For details see man 4 crontabs# Example of job definition:
# .---------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# | | | | |
# * * * * * user-name command to be executed
前三行是运行环境 , 类似于写脚本 里面 的第一行输入 #!/bin/bash 一样
后面是格式介绍,依次从左往右是 分 时 日 月 周 用户名(执行该计划任务的账户) 执行的命令内容或者 制定的脚本目录(该脚本必须有可执行权限)
注意:用户名那里如果是 crontab -e 打开的文件不能写用户名,会直接默认当前用户,否则会出错
通过下图理解
注意区间范围,不能有小数
直接 写数字 说明是到这个时间点就执行
如果 */数字 说明是每隔这个时间点就执行
* ## 代表:取值范围内的任意数字
/n ## 代表:每隔 n 时间就执行
- ## 代表:从某个数字到某个数字
, ## 分隔:几个离散的数字
例子
从左往右: 分 时 日 月 周 注意:周是周几,而不是第几周
* 10 * * * ## 每天 10点 执行
20 */1 * * * ## 每隔一小时的第20分钟执行
*/30 14-16 * * * ## 每天14点到16点每隔30分钟执行
30 23 * * 1,3,6 ## 每周一周三周六的23:30分执行
2/5 10 * * * ## 每天的10点钟从10:02开始,每隔五分钟执行一次
*/10 14-17 * * * root echo "hello world" ## 每天的14-17点每隔10分钟输出 hello world
## 注意:当日或者月和周同时都有的时候,那相当于 or ,每周和每日或者每月满足条件都会执行
比如
0 2 14 * 7 ## 每月14号2:00整或每周日2:00整,这两个时间都执行
30-50/3 12 1 9 * echo "Hi" ## 在9月1号12时 30--50 分间每隔3分钟执行
3 制定crond 周期性 计划任务的方法
方法一是在/etc/crontab 写配置文件,方法二方法三是在 crontab -e 打开的文件里面写配置
注意: crontab -e 打开的文件是当前用户写的,所以格式 **用户名那里不能写,**否则无法执行。
运行 crontab -e 命令时,系统会在临时目录中创建一个临时文件,并使用您默认的文本编辑器打开它。临时文件通常位于 /tmp 目录下,文件名类似于 .crontabXX
到时候可以用 crontab -l 查看 该方法最常用
3.1 编辑 /etc/crontab 文件
适用于:root 用户(时间灵活,须重载crond)
举例:直接命令添加执行
useradd user01
useradd user02
vi /etc/crontab
## 以root 用户身份,每月 1号、15号、28号 的 00:00,执行:/bin/date >> /tmp/root_date.txt 命令 (相当于echo`date` >> /tmp/root_date.txt)
0 0 1,15,28 * * root /bin/date >> /tmp/root_date.txt
## 以<user01 用户身份>,每月 周日 的 00:00,执行:/bin/date >> /tmp/root_date.txt 命令
0 0 * * 0 user01 /bin/date >> /tmp/root_date.txt
## 以<user02 用户身份>,每天 每隔 2小时第5分钟,执行:/bin/date >> /tmp/root_date.txt 命令
5 */2 * * * user02 /bin/date >> /tmp/root_date.txt
systemctl reload crond
3.2 交互式 crontab -e 方式
适用于:当前用户(时间灵活,无须重载crond)
举例:
useradd user01
su -l user01
crontab -e
## 设置:环境变量(★很重要★) 必须要有环境变量才行 类似于 #!/bin/bash
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
## 以当前用户身份,每天 每隔 10分钟,执行:/bin/date >> /tmp/root_date.txt 命令
*/10 * * * * /bin/date >> /tmp/root_date.txt ## 注意:当前用户省略不写,如果写了会出错 (重要)
## crontab -e 方式不用写环境变量
可 crontab -l 查看,注意:本人发现无需设置环境变量,直接设置分时日月周即可
如下测试 需要显式执行
* * * * * /bin/bash -c 'touch /tmp/$(date +\%s).txt'
但在某些情况下(特别是在使用特定命令或脚本时),设置环境变量可以避免潜在的问题。
踩坑:
www-data@39:/k8s-alidata/go/go-micro$ crontab -l
...
0 6 * * * /bin/bash /k8s-alidata/go/go-micro/all-services.sh
## 该脚本调用了 kubectl make go 等诸多命令
正常执行all-services.sh 脚本可以调用成功,如上定时任务不行
发现是没有 kubectl 和 make 和 go 等等诸多这个命令
通过 echo $PATH >> /tmp/1.txt 发现 定时任务环境只有 /usr/bin:/bin
kubectl 路径是 /usr/local/bin/kubectl
make 路径是 /usr/bin/make
脚本前面添加 export PATH=$PATH:/usr/local/bin:/usr/bin 测试还是报错
编译报错,发现还有 go 等等许多命令,我们直接 echo $PATH 查看复制全部环境到脚本里面
然后脚本前面添加 export PATH=(复制的环境) 即可
3.3 标准输入方式
适用于:当前用户(时间灵活,无须重载crond)
非交互式方式
举例:
useradd user01 ## 注意:这样直接写的文件也在 crontab -e 里面
su -l user01
crontab <<EOF
## 设置:环境变量(很重要)
SHELL=/bin/bash # 命令解释器,把命令解析为机器理解的语言
PATH=/sbin:/bin:/usr/sbin:/usr/bin # 环境变量,去哪找命令
MAILTO=root # 发送电子邮件给 root 用户
## 以当前用户身份,每天 每隔 10分钟,执行:/bin/date >> /tmp/root_date.txt 命令
*/10 * * * * /bin/date >> /tmp/root_date.txt
EOF
3.4 利用 crond 预定义目录
适用于:root 用户(时间固定,无须重载crond)
仅适用于周期性 执行<Shell 脚本> ☚ Shell 脚本必须具备<x 可执行权限>
了解<crond 预定义目录>
/etc/cron.d 目录 ## crond 服务自动加载的自定义 计划任务 配置文件的目录## 该目录中的0hourly 配置文件已经计划执行/etc/cron.hourly 目录/etc/cron.hourly 目录 ## 这是预定义的<每小时 计划任务 脚本目录> ☚ 已被默认执行,因为在/etc/cron.d 有写执行该目录,下面几个文件也可以设置/etc/cron.daily 目录 ## 这是预定义的<每天 计划任务 脚本目录> ☚ 未被默认执行
/etc/cron.weekly 目录 ## 这是预定义的<每周 计划任务 脚本目录> ☚ 未被默认执行
/etc/cron.monthly 目录 ## 这是预定义的<每月 计划任务 脚本目录> ☚ 未被默认执行
cd /etc/cron.d ll 发现 0hourly 该文件 ,进去 查看如何配置,从而配置另外几个 文件
cat /etc/cron.d/0hourly
# Run the hourly jobs
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
01 * * * * root run-parts /etc/cron.hourly## 注意:如果是运行目录,要加run-parts(当目录下存在多个脚本的时候)
4 制定crond计划任务
4.1. 计划执行单个命令
举例:
crontab <<EOF## 设置:环境变量(★很重要★)SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin ## 可通过 crontab -e进去该配置文件
MAILTO=root## 以<当前用户身份>,每天 每隔 10分钟,执行:/bin/date >> /tmp/root_date.txt 命令
*/10 * * * * /bin/date >> /tmp/root_date.txt
EOF
4.2.计划执行单个脚本(多个命令)
举例1:
vim /tmp/test.sh ## 写一个脚本
#!/bin/bash
/bin/date > /tmp/root_date.txt chmod +x /tmp/test.sh ## 给脚本可执行权限,不写默认是 a+xcrontab -e
*/10 * * * * /tmp/test.sh ## 配置文件执行该脚本,不需要run-partssystemctl restart crond ## 无需重启
举例2
vi /tmp/test.sh## 设置:环境变量(很重要)
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
## 以当前用户身份,每天 每隔 10分钟,执行:/bin/date >> /tmp/root_date.txt 命令
*/10 * * * * /bin/date >> /tmp/root_date.txtchmod +x /tmp/test.sh
crontab /tmp/test.sh
4.3. 计划执行单个目录(即多个脚本)
举例:
mkdir /tmp/dir01
vi /tmp/dir01/test.sh
#!/bin/bash
/bin/date > /tmp/root_date.txt ## 脚本chmod +x /tmp/dir01/test.shcrontab <<EOF## 设置:环境变量(★很重要★)
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
## 以<当前用户身份>,每天 每隔 10分钟,执行:</dir01 目录>中的<所有可执行 Shell 脚本>
*/10 * * * * run-parts /tmp/dir01 ## 运行目录需要 run-parts
EOF
5 查看crond 计划任务
举例:
crontab -l ## 查看:<当前用户>的<crond 周期性 计划任务>
crontab -l -u user01 ## 查看:<指定用户>的<crond 周期性 计划任务>
注意:只能查看 crontab -e 的计划任务,并不能查看到主配置文件的任务
6 删除crond 计划任务
举例:
crontab -r ## 删除:<当前用户>的<crond 周期性 计划任务>
crontab -r -u user01 ## 删除:<指定用户>的<crond 周期性 计划任务>
7 管理crond 计划任务权限
★ **处于完全考虑:**我们需要对<制定 cron 周期性 计划任务>这个<操作行为>进行管控,控制流程如下:
(1) 首先:读取</etc/cron.allow文件>,检查<该用户>是否被<明确允许>
</etc/cron.allow文件>优先级最高,最严厉:默认拒绝一切,除非<明确允许>
对<root 用户>无效
</etc/cron.allow文件>默认未创建,需手动创建
(2) 其次:读取</etc/cron.deny文件>,检查<该用户>是否被<明确拒绝>
</etc/cron.deny文件>优先级最低,最宽松:默认允许一切,除非<明确拒绝>
对<root 用户>无效
(3) 最后:如果</etc/cron.allow 和 /etc/cron.deny>均不存在,则仅允许<root 用户>制定<cron 周期性 计划任务>
注意:和 at 一次性任务那里权限差不多,都是黑名单白名单。
示例1:允许一切,明确拒绝<user01 和 user02>
vi /etc/cron.deny ## 一行仅写一个<用户帐号>
user01
user02
示例2:拒绝一切,明确允许<user01 和 user02>
vi /etc/cron.allow ## 一行仅写一个<用户帐号>
user01
user02