Linux(一次性和周期性任务cron)

后面也会持续更新,学到新东西会在其中补充。

建议按顺序食用,欢迎批评或者交流!

缺什么东西欢迎评论!我都会及时修改的!

在这里真的很感谢这位老师的教学视频让迷茫的我找到了很好的学习视频

王晓春老师的个人空间-王晓春老师个人主页-哔哩哔哩视频


任务计划

未来的某时间点执行一次任务

  • at 指定时间点,执行一次性任务
  • batch 系统自行选择空闲时间去执行此处指定的任务

周期性运行某任务

  • cron

一次性任务 at

at工具

  • 由包at提供
  • 依赖与atd服务
  • at队列存放在/var/spool/at目录中
  • 执行任务时PATH变量值和当前用户身份一致
bash 复制代码
[root@CentOS8 ~]# rpm -ql at

包里包括了很多可执行文件

bash 复制代码
服务开启是自动启动的
[root@CentOS8 ~]# systemctl status atd.service
● atd.service - Job spooling tools
   Loaded: loaded (/usr/lib/systemd/system/atd.service; enabled; vendor preset:>
   Active: active (running) since Wed 2024-12-18 12:52:16 CST; 6min ago
 Main PID: 1289 (atd)
    Tasks: 1 (limit: 12252)
   Memory: 424.0K
   CGroup: /system.slice/atd.service
           └─1289 /usr/sbin/atd -f

Dec 18 12:52:16 CentOS8 systemd[1]: Started Job spooling tools.

指定任务生成命令

bash 复制代码
[root@CentOS8 ~]# at
Garbled time
at 后面需要跟上时间


[root@CentOS8 ~]# date
Wed Dec 18 13:00:38 CST 2024

[root@CentOS8 ~]# at 13:10
warning: commands will be executed using /bin/sh 如果写的脚本是以sh来执行的要符合sh的语法
at> echo $PATH
at> touch /data/at.log
at> <EOT> ctrl + D退出
job 1 at Wed Dec 18 13:10:00 2024 

查看任务是否生成

bash 复制代码
[root@CentOS8 ~]# at -l
1       Wed Dec 18 13:10:00 2024 a root

时间当了at.log生成了但是echo没有生成,因为不知道往哪个终端生成。

注意:

  • 作业执行命令的结果中标准输出和错误以用户身份发送邮件通知给 root
  • 默认CentOS 8 最小化安装没有安装邮件服务,需要自行安装。

范例:

bash 复制代码
[root@CentOS8 ~]# dnf install postfix -y
[root@CentOS8 ~]# systemctl enable --now postfix

[root@CentOS8 ~]# yum -y install mailx
[root@CentOS8 ~]# rpm -qf /usr/bin/mail

任务中写的echo 因为不知道输出到哪就发邮箱给 root

bash 复制代码
[root@CentOS8 ~]# mail
Heirloom Mail version 12.5 7/5/10.  Type ? for help.
"/var/spool/mail/root": 2 messages 2 new
>N  1 root                  Wed Dec 18 13:10  15/605   "Output from your job " 作业1
 N  2 wang@CentOS8.localdo  Wed Dec 18 13:17  14/566   "Output from your job " 作业2


& 2
Message  2:
From wang@CentOS8.localdomain  Wed Dec 18 13:17:00 2024
Return-Path: <wang@CentOS8.localdomain>
X-Original-To: root
Delivered-To: root@CentOS8.localdomain
Subject: Output from your job        2
To: root@CentOS8.localdomain
Date: Wed, 18 Dec 2024 13:17:00 +0800 (CST)
From: wang@CentOS8.localdomain
Status: R

/home/wang/.local/bin:/home/wang/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin
生成了路径信息。

at 任务生成以后重启是否会丢失呢

bash 复制代码
[root@CentOS8 ~]# su - wang
[wang@CentOS8 ~]$ at 13:17
warning: commands will be executed using /bin/sh
at> echo $PATH
at> touch wang.log
at> <EOT>
job 2 at Wed Dec 18 13:17:00 2024
[wang@CentOS8 ~]$ at -l
2       Wed Dec 18 13:17:00 2024 a wang
[wang@CentOS8 ~]$ ll /var/spool/at/
ls: cannot open directory '/var/spool/at/': Permission denied
[wang@CentOS8 ~]$ exit
logout
[root@CentOS8 ~]# ll /var/spool/at/
total 4
-rwx------. 1 wang wang 2552 Dec 18 13:14 a0000201b91b1d 在磁盘上保存了计划
drwx------. 2 root root    6 Dec 18 13:10 spool

at 执行过时任务

bash 复制代码
[root@CentOS8 ~]# su - wang
[wang@CentOS8 ~]$ date
Wed Dec 18 13:20:19 CST 2024
[wang@CentOS8 ~]$ at 13:19
warning: commands will be executed using /bin/sh
at> wall test log
at> <EOT>
job 3 at Thu Dec 19 13:19:00 2024  在第二天的13:19执行
[root@CentOS8 ~]# at -l
3       Thu Dec 19 13:19:00 2024 a wang

[root@CentOS8 ~]# vi /var/spool/at/a0000301b920bf

查看任务指定后文件

bash 复制代码
[root@CentOS8 ~]# at -l
3       Thu Dec 19 13:19:00 2024 a wang
[root@CentOS8 ~]# at -c 3

删除任务

bash 复制代码
[root@CentOS8 ~]# at -d 3
[root@CentOS8 ~]# at -l

为什么wang命令没有权限访问文件夹权限居然还可以生成文件?

bash 复制代码
[wang@CentOS8 ~]$ ll /var/spool/at/
ls: cannot open directory '/var/spool/at/': Permission denied

因为suid,普通用户执行at 相当于是变成了 root

bash 复制代码
[root@CentOS8 ~]# ll `which at`
-rwsr-xr-x. 1 root root 61688 May 11  2019 /usr/bin/at

不通过交互式通过标准输入

bash 复制代码
[root@CentOS8 ~]# date
Wed Dec 18 13:36:42 CST 2024
[root@CentOS8 ~]# echo wall at job | at 13:38
warning: commands will be executed using /bin/sh
job 4 at Wed Dec 18 13:38:00 2024
[root@CentOS8 ~]# at -l
4       Wed Dec 18 13:38:00 2024 a root

wall 广播命令只要在机器上登录的用户会接受到信息因为是广播机制

通过文件重定向到at

bash 复制代码
[root@CentOS8 data]# vi root.sh
[root@CentOS8 data]# touch {1..10}.txt
[root@CentOS8 data]# ll
total 4
-rw-r--r--. 1 root root  0 Dec 18 13:40 10.txt
-rw-r--r--. 1 root root  0 Dec 18 13:40 1.txt
-rw-r--r--. 1 root root  0 Dec 18 13:40 2.txt
-rw-r--r--. 1 root root  0 Dec 18 13:40 3.txt
-rw-r--r--. 1 root root  0 Dec 18 13:40 4.txt
-rw-r--r--. 1 root root  0 Dec 18 13:40 5.txt
-rw-r--r--. 1 root root  0 Dec 18 13:40 6.txt
-rw-r--r--. 1 root root  0 Dec 18 13:40 7.txt
-rw-r--r--. 1 root root  0 Dec 18 13:40 8.txt
-rw-r--r--. 1 root root  0 Dec 18 13:40 9.txt
-rw-r--r--. 1 root root 13 Dec 18 13:40 root.sh
[root@CentOS8 data]# cat root.sh
ls /data/ -l

[root@CentOS8 data]# date
Wed Dec 18 13:41:52 CST 2024
[root@CentOS8 data]# at 13:43 < root.sh  重定向到at
warning: commands will be executed using /bin/sh
job 5 at Wed Dec 18 13:43:00 2024
[root@CentOS8 data]# at -l
5       Wed Dec 18 13:43:00 2024 a root

半小时触发

bash 复制代码
[root@CentOS8 ~]# at now+30minutes
warning: commands will be executed using /bin/sh
at> wall class is over
at> <EOT>
job 6 at Wed Dec 18 14:17:00 2024
[root@CentOS8 ~]# at -l
6       Wed Dec 18 14:17:00 2024 a root

at 任务执行方式:

  • 交互式
  • 输入重定向
  • at -f file

黑名单和白名单

bash 复制代码
[root@CentOS8 ~]# ll /etc/at.deny
-rw-r--r--. 1 root root 1 May 11  2019 /etc/at.deny
[root@CentOS8 ~]# ll /etc/at.allow
ls: cannot access '/etc/at.allow': No such file or directory

黑名单如有用户放入则拒绝执行at命令

bash 复制代码
[root@CentOS8 ~]# vi /etc/at.deny
[root@CentOS8 ~]# cat !*
cat /etc/at.deny
wang
[root@CentOS8 ~]# su - wang
[wang@CentOS8 ~]$ at 15:33
You do not have permission to use at.

如果wang用户之前有任务

wang用户进入黑名单以后wang用户就不能再创建新的计划任务了不代表不能执行之前的任务。

用户在黑名单又在白名单

bash 复制代码
[root@CentOS8 ~]# vi /etc/at.deny
[root@CentOS8 ~]# vi /etc/at.allow
[root@CentOS8 ~]# cat /etc/at.allow
wang
[root@CentOS8 ~]# cat /etc/at.deny
wang
[root@CentOS8 ~]# su - wang
[wang@CentOS8 ~]$ at -l
[wang@CentOS8 ~]$ at 12:00
warning: commands will be executed using /bin/sh
at> echo 123
at> <EOT>
job 7 at Thu Dec 19 12:00:00 2024
[wang@CentOS8 ~]$ at -l
7       Thu Dec 19 12:00:00 2024 a wang

是可以执行任务的。allow的优先级高级deny

周期性任务计划 cron

bash 复制代码
[wang@CentOS8 ~]$ rpm -q cronie
cronie-1.5.2-4.el8.x86_64
[wang@CentOS8 ~]$ rpm -ql cronie
/etc/cron.d
/etc/cron.d/0hourly
....
bash 复制代码
[wang@CentOS8 ~]$ systemctl status crond
● crond.service - Command Scheduler
   Loaded: loaded (/usr/lib/systemd/system/crond.service; enabled; vendor preset: enabled)
   Active: active (running) since Wed 2024-12-18 12:52:16 CST; 1h 17min ago
 Main PID: 1285 (crond)
    Tasks: 1 (limit: 12252)
   Memory: 3.6M
   CGroup: /system.slice/crond.service
           └─1285 /usr/sbin/crond -n
bash 复制代码
[wang@CentOS8 ~]$ ll /etc/cron.* -d
drwxr-xr-x. 2 root root 39 Dec 17 18:00 /etc/cron.d
drwxr-xr-x. 2 root root 23 Dec 17 17:58 /etc/cron.daily
-rw-r--r--. 1 root root  0 Nov  9  2019 /etc/cron.deny
drwxr-xr-x. 2 root root 22 Dec 17 17:58 /etc/cron.hourly
drwxr-xr-x. 2 root root  6 Jan 12  2021 /etc/cron.monthly
drwxr-xr-x. 2 root root  6 Jan 12  2021 /etc/cron.weekly
bash 复制代码
[wang@CentOS8 ~]$ ll /usr/bin/run-parts
-rwxr-xr-x. 1 root root 1983 Jan 12  2021 /usr/bin/run-parts
[wang@CentOS8 ~]$ /usr/bin/run-parts
Usage: run-parts [--list | --test] <dir> 

Usage: run-parts [--list | --test] <dir> 后面允许跟一个文件夹把后面这个文件夹里的所有可执行文件进行执行,将来可以把干的活放到这一个文件夹里面

bash 复制代码
[root@CentOS8 data]# vi f1.sh
[root@CentOS8 data]# vi f2.sh
[root@CentOS8 data]# cat f1.sh
#!/bin/bash
echo f1.sh
[root@CentOS8 data]# cat f2.sh
#!/bin/bash
echo f2.sh

使用run-parts 执行文件夹里面所有可执行文件

bash 复制代码
[root@CentOS8 data]# chmod +x /data/*
[root@CentOS8 data]# run-parts /data/
/data/f1.sh:

f1.sh
/data/f2.sh:

f2.sh

cron 依赖于crond服务,确保crond守护处于运行状态:

bash 复制代码
#CentOS 7 以后版本
systemctl status crond

#CentOS 6:
service crond status

任务区别

系统记录的计划任务通常来讲要写入总的配置文件想改需要有权限

bash 复制代码
[root@CentOS8 data]# ll /etc/crontab
-rw-r--r--. 1 root root 451 Jan 12  2021 /etc/crontab
[root@CentOS8 data]# vi /etc/crontab
  • 空格不限
  • * 就是每一天
  • 5,7 星期5星期7
  • 9-12 9天10天11天12天
  • 01 * * * *每小时的第一分钟
  • root 用户
  • echo $PATH 命令

分时天月星期

bash 复制代码
1 15 18,19,20 * 3-4 root echo $PATH

root 用户打印 echo $PATH 每个月的18,19,20天 15:01 星期三星期四

查看日志服务

bash 复制代码
[root@CentOS8 data]# tail /var/log/cron -f
Dec 18 13:43:01 CentOS8 anacron[1414]: Normal exit (1 job run)
Dec 18 14:01:01 CentOS8 CROND[3523]: (root) CMD (run-parts /etc/cron.hourly)
Dec 18 14:01:01 CentOS8 run-parts[3523]: (/etc/cron.hourly) starting 0anacron
Dec 18 14:01:01 CentOS8 run-parts[3523]: (/etc/cron.hourly) finished 0anacron
Dec 18 14:17:00 CentOS8 atd[3598]: Starting job 6 (a0000601b91b59) for user 'root' (0)
Dec 18 14:26:55 CentOS8 run-parts[3629]: (/data/) starting f1.sh
Dec 18 14:26:55 CentOS8 run-parts[3629]: (/data/) finished f1.sh
Dec 18 14:26:55 CentOS8 run-parts[3629]: (/data/) starting f2.sh
Dec 18 14:26:55 CentOS8 run-parts[3629]: (/data/) finished f2.sh
Dec 18 14:54:01 CentOS8 crond[1285]: (*system*) RELOAD (/etc/crontab)

查看邮件里面的输出信息

bash 复制代码
You have new mail in /var/spool/mail/root
[root@CentOS8 ~]# mail

如果想删除邮件文件
[root@CentOS8 cron.daily]# rm -rf /var/spool/mail/*

需要注意的是环境变量

比平常的执行路径少了很多

新建一个文件执行命令放在/etc/cron.d文件夹下

bash 复制代码
[root@CentOS8 ~]# cd /etc/cron.d
[root@CentOS8 cron.d]# ll
total 8
-rw-r--r--. 1 root root 128 Nov  9  2019 0hourly
-rw-r--r--. 1 root root 108 Aug 10  2021 raid-check
[root@CentOS8 ~]# 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 //扫描文件夹里面所有可执行文件进行执行每小时第1分钟
新建一个任务文件
[root@CentOS8 cron.d]# vi test.sh
[root@CentOS8 cron.d]# cat test.sh
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin
MAILTO=root
* * * * * root echo $PATH  每分钟打印执行路径

/etc/crontab 是总的计划! /etc/cron.d/目录下可以写各自的周期计划。

bash 复制代码
[root@CentOS8 cron.daily]# ls /etc/anacrontab
/etc/anacrontab
[root@CentOS8 cron.daily]# cat !*
cat /etc/anacrontab
# /etc/anacrontab: configuration file for anacron

# See anacron(8) and anacrontab(5) for details.

SHELL=/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
# the maximal random delay added to the base delay of the jobs
RANDOM_DELAY=45 随机延迟为了防止计划任务过多
# the jobs will be started during the following hours only
START_HOURS_RANGE=3-22
凌晨3点到22点之间 自动会启动这个功能

#period in days   delay in minutes   job-identifier   command
1       5 开机五分钟以后检测      cron.daily              nice run-parts /etc/cron.daily
检测关机导致没有每天执行的任务
7       25      cron.weekly             nice run-parts /etc/cron.weekly
开机25分钟以后检测关机导致没有每周执行一次
@monthly 45     cron.monthly            nice run-parts /etc/cron.monthly

即使关机了没执行开机了也会自动的给执行。

logrotate 日志的处理

bash 复制代码
[root@CentOS8 cron.daily]# pwd
/etc/cron.daily
[root@CentOS8 cron.daily]# ll
total 4
-rwxr-xr-x. 1 root root 189 Jan  4  2018 logrotate

创建计划任务

crontab -e 默认是当前用户创建计划任务

crontab -e -u wang 指定用户创建计划任务

bash 复制代码
[root@CentOS8 cron.daily]# su - wang
[wang@CentOS8 ~]$ crontab -e 


30 2 1-10,20 * 1-5 wang echo $PATH
每个月 1-10号+20号 周一到周五 凌晨2点30 输出路径变量

[wang@CentOS8 ~]$ man crontab
[wang@CentOS8 ~]$ man 5 crontab
bash 复制代码
"30 4 1,15 * 5" would cause a command to be run at 4:30 am on the 1st and 15th of each month, plus every Friday.
将导致命令在每个月 1 日和 15 日以及每个星期五的凌晨 4:30 运行。

日期号和星期的关系是或

修改显示格式

bash 复制代码
[root@CentOS8 ~]# vi /etc/profile.d/env.sh
[root@CentOS8 ~]# cat !*
cat /etc/profile.d/env.sh
export EDITOR=vim

editor是系统自带的变量,影响了很多管理工具默认的文本编辑器。
editor 修改了系统调用让他调用的是vim

需要把窗口关掉才生效。

面试题

11月的每天的6-12点之间每隔2小时执行/app/bin/test.sh

bash 复制代码
*/10 每十分钟的意思 10-50/10 每隔10分钟执行一次
0 6-12/2 * 11 * /app/bin/test.sh

每两分钟执行一次

*/1 就是 *

crontab -e 不用输入用户名

bash 复制代码
[root@RockyLinux9 ~]#crontab -e
*/2 * * * * echo $PATH

[root@RockyLinux9 ~]#crontab -l
*/2 * * * * echo $PATH
bash 复制代码
[root@CentOS8 ~]# crontab -e
crontab: installing new crontab
[root@CentOS8 ~]# crontab -l
*/2 * * * * echo $PATH
*/2 * * * * useradd haha

路径没有包括/usr/sbin 因此命令没有执行成功!

解决方案把所有路径信息都输入!

bash 复制代码
[root@CentOS8 ~]# crontab -l
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
*/1 * * * * echo $PATH
*/1 * * * * useradd haha;echo $PATH
bash 复制代码
清除定时任务
[root@CentOS8 ~]# crontab -r
[root@CentOS8 ~]# crontab -l
no crontab for root

crontab -e的文件放在哪的呢?

/var/spool/cron/

bash 复制代码
[root@CentOS8 ~]# crontab -e
no crontab for root - using an empty one
crontab: installing new crontab
[root@CentOS8 ~]# crontab -l
* * * * * echo $PATH
[root@CentOS8 ~]# cat /var/spool/cron/root
* * * * * echo $PATH
[root@CentOS8 ~]# su - wang
[wang@CentOS8 ~]$ crontab -e
no crontab for wang - using an empty one
crontab: installing new crontab
[wang@CentOS8 ~]$ crontab -l
* * * * * echo $PATH
[wang@CentOS8 ~]$ ls /var/spool/cron/
ls: cannot open directory '/var/spool/cron/': Permission denied
[wang@CentOS8 ~]$ exit
logout
You have new mail in /var/spool/mail/root
[root@CentOS8 ~]# ls /var/spool/cron/
root  wang

显示每10分钟显示磁盘信息

sed 万能的

bash 复制代码
[root@CentOS8 ~]# df | sed -En '/^\/dev\/sd/s@^([^ ]+).* ([0-9]+)%.*@\1 \2@p'
/dev/sda1 23

[root@CentOS8 data]# vi disk_check.sh
You have new mail in /var/spool/mail/root
[root@CentOS8 data]# cat disk_check.sh
#!/bin/bash
WARNING=10 #警告变量
#while read DEVICE USE 逐行处理device 和 use
df | sed -En '/^\/dev\/sd/s@^([^ ]+).* ([0-9]+)%.*@\1 \2@p' | while read DEVICE USE;do
    [ $USE -gt $WARNING ] && echo "$DEVICE will be full,USE:$USE" | mail -s diskfull root
done

[root@CentOS8 data]# bash disk_check.sh
[root@CentOS8 data]# chmod +x disk_check.sh

将我们写好的脚本放入周期计划

bash 复制代码
[root@CentOS8 data]# crontab -e
no crontab for root - using an empty one
crontab: installing new crontab
[root@CentOS8 data]# crontab -l
* * * * * disk_check.sh
[root@CentOS8 data]# mv disk_check.sh /usr/bin/

方法二:

bash 复制代码
[root@CentOS8 data]# mv /usr/bin/disk_check.sh /data/
[root@CentOS8 data]# crontab -l
* * * * * /data/disk_check.sh

打包目录到指定目录下

bash 复制代码
#!/bin/bash
tar cf /opt/nginx_access_log_`date +%F_%H_%M_%S`.tar.gz /app/nginx/logs/* &> /dev/null

试验一下:

bash 复制代码
[root@CentOS8 data]# vi tar.sh
[root@CentOS8 data]# cat tar.sh
#!/bin/bash
tar cf /data/data_`date +%F_%H_%M_%S`.tar.gz /data/* &> /dev/null
[root@CentOS8 data]# crontab -e
crontab: installing new crontab
[root@CentOS8 data]# crontab -l
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
* * * * * /data/tar.sh

成功 !

需要注意的问题

%表示命令结束%后面的内容作为命令的stdin

bash 复制代码
[root@CentOS8 data]# crontab -l
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
* * * * * /bin/cp -a /etc/ /data/etc`date +\%F_\%T`

写计划脚本有标准输出 %这种不要直接用

由于默认都会把输出和错误以邮件方式发送

写计划脚本和人机交互脚本的风格是不一样的

最好把标准输出给隐藏起来

不能写成*/7 60/7除不尽的

可以用sleep操作

bash 复制代码
[root@CentOS8 data]# date;sleep 7m;echo test;date
Wed Dec 18 22:56:35 CST 2024

练习

待续这里

参考文献

3一次性和周期性计划任务_哔哩哔哩_bilibili

4周期性计划任务cron_哔哩哔哩_bilibili

总结

所有命令都需要反复敲来实验来记忆,本人基本上是个人理解加参考其他大佬的肯定有很多问题欢迎指正,我会及时修改。

相关推荐
amazinging几秒前
北京-4年功能测试2年空窗-报培训班学测开-第三十九天
python·学习·appium
庸子1 分钟前
基于Jenkins和Kubernetes构建DevOps自动化运维管理平台
运维·kubernetes·jenkins
每次的天空23 分钟前
Android-自定义View的实战学习总结
android·学习·kotlin·音视频
眠修24 分钟前
Kuberrnetes 服务发布
linux·运维·服务器
重庆小透明29 分钟前
力扣刷题记录【1】146.LRU缓存
java·后端·学习·算法·leetcode·缓存
好奇的菜鸟1 小时前
Docker 配置项详解与示例
运维·docker·容器
xcs194052 小时前
集运维 麒麟桌面版v10 sp1 2403 aarch64 离线java开发环境自动化安装
运维·自动化
BAOYUCompany2 小时前
暴雨服务器成功中标华中科技大学集成电路学院服务器采购项目
运维·服务器
超龄超能程序猿2 小时前
Bitvisse SSH Client 安装配置文档
运维·ssh·github
许白掰3 小时前
【stm32】HAL库开发——CubeMX配置RTC,单片机工作模式和看门狗
stm32·单片机·嵌入式硬件·学习·实时音视频