第一章 Linux的例行性工作(计划任务)

发布于:2025-05-30 ⋅ 阅读:(15) ⋅ 点赞:(0)

场景:

  • 生活中,我们有太多场景需要使用到闹钟,比如早上 7 点起床,下午 4 点开会,晚上 8 点购物,等等。

  • 在 Linux 系统里,我们同样也有类似的需求。比如我们想在凌晨 1 点将文件上传服务器,或者在晚上 10 点确认系统状态,等等。

  • 但我们不可能一直守在电脑前,毕竟我们也需要下班/睡觉,还要陪女朋友(new一个也行)。而且即使在上班期间,如果到点了还需要人工操作,未免效率太低了。

  • at 命令就是为这个需求而诞生的。使用 at 命令,你可以在特定时间自动完成你所设定的任务,也可以实现自动化,非常方便快捷。

单一执行的例行性任务--at(一次性)

安装

at命令需要安装

[root@server ~]# yum  install  at  -y
[root@server ~]# at  -V   # 大写V
at version 3.2.2

启动服务

[root@server ~]# systemctl start  atd
[root@server ~]# systemctl enable  --now  atd  # 设置开机启动
[root@server ~]# systemctl  status  atd  # 查看状态

at命令详解

格式

at  -参数   日期时间

参数
-m:当任务完成后,即使没有标准输出,也会给用户发送邮件
-l:列出系统上所有用户的at任务,等价于atq
-d:删除或取消一个任务
-v:使用时间格式,列出at任务
-c:可以列出任务之后的命令内容
-f:从文件中读取
时间格式

        实验1
  • 延迟执行ls /root ,并将结果写入到at.txt中

    [root@server ~]# at  14:17
    warning: commands will be executed using /bin/sh
    at> ls  /root  >  at.txt
    at> <EOT>      # 点击ctrl+d 结束交互性界面
    
    [root@server ~]# at  -l   # 查看已存在的计划任务
    3	Thu May 25 14:17:00 2023 a root
    [root@server ~]# atq      # 同上
    3	Thu May 25 14:17:00 2023 a root
    实验2
  • 不使用交互性命令实现,通过管道符命令执行

    [root@server ~]# echo  "echo  'hello  again'  >>  at.txt" | at  now  +1  minute

    注意

    - at命令只要指定的时间正确,就可以执行对应的命令
    - at命令的输出结果不会显示到屏幕上   
    - at命令中执行的命令最好使用绝对路径,不容易报错
    - 过程:输入at   时间 -> 回车 ->输入执行的命令->ctrl+d退出at
    - at命令只会执行一次

at命令执行过程分析
  • 第一步:寻找/etc/at.allow (白名单)是否存在,写在该文件中用户才可执行at命令

  • 第二步:若/etc/at.allow不存在,则寻找/etc/at.deny(黑名单)文件,写在该文件中的用户不能使用at命令

  • 第三步:若两个文件都不存在则只有root用户可以使用at命令

  • 注意:若拒绝某用户使用at命令则可以将用户名写入到/etc/at.deny中

        实验3
  • 设置某账户at命令不可用

    [root@server ~]# useradd  ce1   # 新建账户
    [root@server ~]# passwd  ce1    # 设置密码
    更改用户 ce1 的密码 。
    新的密码:                       # 654321
    无效的密码: 密码少于 8 个字符
    重新输入新的密码:                # 654321
    passwd:所有的身份验证令牌已经成功更新。
    [root@server ~]# tail  -1  /etc/passwd  # 倒叙查看账户管理文件
    ce1:x:1001:1001::/home/ce1:/bin/bash
    [root@server ~]# vim  /etc/at.deny   # 设置黑名单
    ce1                                  # 输入
    
    [root@server ~]# su  ce1             # 切换账户
    [ce1@server root]$ cd  ~
    [ce1@server ~]$ at  14:36         # 测试,at命令不可用
    You do not have permission to use at.
    [ce1@server ~]$ su  root         # 切换到root账户
    密码: 
    su: 拒绝权限
    
    # 安全考虑,openEuler做了用户权限切换限制,解决方法如下:
    # 重新开启一个ssh连接,以root账户登录
    [root@server ~]# vim  /etc/pam.d/su # PAM(Pluggable Authentication Modules)负责系统中很多应用程序的登录认证,安全设置问题
    
    # 注释掉第21行:
    # auth          required        pam_wheel.so use_uid
    
    # 保存关闭后,切换到原ssh连接
    [ce1@server ~]$ su  root
    密码: 
    
    Welcome to 5.10.0-153.12.0.92.oe2203sp2.x86_64
    
    System information as of time: 	2023年 11月 15日 星期三 13:38:45 CST
    
    System load: 	0.00
    Processes: 	139
    Memory used: 	9.8%
    Swap used: 	0%
    Usage On: 	7%
    IP address: 	192.168.48.130
    Users online: 	2
    
    [root@server ce1]# cd  ~
    [root@server ~]# 

    循环执行的例行性任务--crontab(周期性)

    crontd服务

  • at 命令是在指定的时间只能执行一次任务,crontab 命令可以循环重复的执行定时任务,与Windows 中的计划任务有些类似

  • crond 是 Linux 下用来周期地执行某种任务或等待处理某些事件的一个守护进程,在安装完成操作系统后,默认会安装 crond 服务工具,且 crond 服务默认就是自启动的,若需要安装则执行如下命令:

    [root@server ~]# yum  install  crontabs    # 安装,注意包名
    
    [root@server ~]# systemctl status  crond   # 查看状态

  • crond 进程==每分钟==会定期检查是否有要执行的任务,如果有,则会自动执行该任务,crontab 命令需要 crond 服务支持

  • linux 任务调度的工作主要分为以下两类:

    • 系统执行的工作:系统周期性所要执行的工作,如备份系统数据、清理缓存

    • 个人执行的工作:某个用户定期要做的工作,例如每隔 10 分钟检查邮件服务器是否有新信,这些工作可由每个用户自行设置

crontab工作过程

  • 当系统中有 /etc/cron.allow 文件时,只有写入此文件的用户可以使用 crontab 命令,没有写入的用户不能使用 crontab 命令。同样,如果有此文件,/etc/cron.deny 文件会被忽略,因为 /etc/cron.allow 文件的优先级更高

  • 当系统中只有 /etc/cron.deny 文件时,写入此文件的用户不能使用 crontab 命令,没有写入文件的用户可以使用 crontab 命令

  • crontab 执行的每一项工作都会被 记录到 /var/log/cron 这个日志文件中

  • 当用户使用 crontab 新建工作之后,该项工作就会被记录到 /var/spool/cron/目录里面

crontab命令详解

格式
crontab  [-u  user]  [-l| -r | -e]  
参数

执行crontab 命令就是在修改 /var/spool/cron 中的定时任务文件。

编辑crontab
  • 格式:

    [root@server ~]# crontab  -e

写入的命令格式:每一行书写一个工作,每个工作共有6个字段

*/5 6-8 * 8 1  /bin/bash  /test.sh
特殊字符

实验4

编写脚本test1.sh

[root@server ~]# vim  test1.sh

#!/bin/bash
while :
do
        echo  "this is my test sh"$(date)  >>  /root/cro.txt
        sleep  1
done 

设置循环周期性任务

[root@server ~]# crontab  -e
*/1 * * * *   sh   /root/test1.sh

注意:crond服务是自动启动的,crontab命令只要保存退出后就会生效

查看任务:

[root@server ~]# crontab  -l
*/1 * * * * sh  /root/test.sh

删除任务

[root@server ~]# crontab  -r   # 删除
[root@server ~]# crontab  -l   # 查看列表
no crontab for root

此实验还需终止循环进程

[root@server ~]# ps  -aux  |  grep  test1
[root@server ~]# kill  进程号
实验5
  • 让系统在每周1凌晨6点重启一次

[root@server ~]# crontab  -e
0 6 * * 1  /sbin/shutdown  -r now
实验6
  • 设置邮件发送告警功能,每1分钟发送一封邮件

  • qq邮箱设置:

开启pop3/SMTP 服务:

复制授权码:

安装邮件服务

[root@server ~]# yum  install  mailx  -y

配置邮件服务

[root@server ~]# vim  /etc/mail.rc
# 最后一行添加以下内容:
set  from=17674044@qq.com
set  smtp=smtp.qq.com
set  smtp-auth-user=17674044@qq.com
set  smtp-auth-password=do***cvqdubqbibj
set  smtp-auth=login

# 注意:该文件输入完毕有的系统需要强制保存退出,输入wq!

测试邮件服务

[root@server ~]# echo  "testmail"  |  mail  -s  "testmail"  17674044@qq.com

设置定时任务

[root@server ~]# crontab  -e
MAILTO=17674044@qq.com

* * * * *   echo  "警告,SERVER服务器内存较低,速处理"  |  mail -v -s  "告警邮件"  17674044@qq.com  
书写定时任务的注意事项
  • 6 个字段都不能为空,如果不确定则使用*表示任意时间

  • crontab命令任务的最小时间单位为分钟,最大有效时间为月,如:2024年某时执行、3点30分30秒这样的时间日期无法被识别

  • 定义时间时,日期和星期最好不要一起出现,由于都是以天为单位,非常让管理员混淆

  • 在定时任务中不能,不管是写命令还是在脚本中写命令,最好都用==绝对路径==,相对路径有时会报错

系统级别的计划任务

  • crond 服务除了会在工作时查看 /var/spool/cron 文件夹下的定时任务文件以外,还会查看 /etc/cron.d 目录。而在 /etc/anacrontab 文件里面存放每天、每周、每月需要执行的系统任务。

    [root@server ~] # ls -l /etc/ | grep cron*
    cron.d			# 系统定时任务
    cron.daily		# 每天的任务
    cront.deny		# 定时任务黑名单
    cron.hourly		# 每小时执行的任务
    cron.monthly	# 每月的定时任务
    crontab			# 定义任务管理文件
    cron.weekly		# 每周的定时任务
  • crontab -e  时每个用户都可以执行的命令,但有时定时任务必须由系统执行,此时就需要编辑/etc/crontab配置文件来实现

  • 主配置文件:

    [root@server ~]# vim  /etc/crontab
  • 仅能通过root定义,不可以使用普通账户身份去执行计划任务

  • 方法:在/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
    • 分析

      • SHELL=/bin/bash : 指定系统使用那个shell解释器去执行

      • PATH=/sbin:/bin:/usr/sbin:/usr/bin : 系统执行命令的搜索路径

      • MAILTO=root : 表示执行任务的信息通过邮件发送给谁

      • user-name : 表示执行命令的用户是谁

    • 例1:编写脚本testcrontab.sh,将时间写入/t1.txt文件中,每周二11点循环执行

      [root@server ~]# vim  testcrontab.sh
      #!/bin/bash
      date >> /t1.txt
      [root@server ~]# vim  /etc/crontab
      0 11 * * 2  root  /bin/bash  /root/testcrontab.sh
    • 例2:每天6:00点将日志/var/log/messages 文件备份到/backup目录中,备份后的日志文件名修改为logfileYYYY-MM-DD-HH:MM:SS

      [root@server ~]# mkdir  /backup     # 新建目录
      
      [root@server ~]# vim  /etc/crontab  # 编辑系统计划任务
      0 6 * * *   root   /bin/cp  /var/log/messages /backup/logfile`date  +\%Y-\%m-\%d-\%H:\%M:\%S`
      
      # 注意:可以使用* * * * * 进行测试
      # 反引号`` 表示将引起的内容识别为命令
      # 在crontab系统中%表示换行,需要增加转义符\
      
      

      练习

      题目:

      1. 每分钟执行命令
      
      2. 每小时执行
      
      3. 每天凌晨3点半和12点半执行脚本
      
      4. 每隔6小时,相当于6,12,18,24点半执行脚本
      
      5. 30代表半点,8-18/2表示早上8点到下午18点之间每隔2小时执行脚本
      
      6. 每天晚上9点30重启nginx
      
      7. 每月1和10号凌晨4点45执行脚本
      
      8. 每周六和周日凌晨1点10分执行命令
      
      9. 每天18点到23点之间,且每隔30分钟执行一次
      
      10. 每隔一小时执行一次
      
      11. 在4月份的周一到周三的上午11点执行脚本
      
      12. 每天早上7点到上午11点且每2小时执行一次
      
      13. 每天6点执行脚本
      
      14. 每周六凌晨4点执行
      
      15. 每周六凌晨4点05执行
      
      16. 每天8:40执行
      
      17. 在每天10:31且每隔2小时执行一次
      
      18. 每周一到周五2:00执行
      
      19. 每周一到周五8:00和9:00执行
      
      20. 每天10:00,16:00执行
      1.  */1 * * * * cmd
      2.  0 * * * * cmd
      3.  30 3,12 * * * cmd
      4.  30 */6 * * * cmd
      5.  30 8-18/2 * * * cmd
      6.  30 21 * * * /usr/bin/systemctl restart nginx
      7.  45 4 1,10 * * cmd
      8.  10 1 * * 6,0 cmd
      9.  0,30 18-23 * * * cmd  或  */30 18-23 * * * cmd
      10.  0 */1 * * * cmd  或  0 * * * * cmd
      11.  0 11 * 4 1-3 cmd
      12.  0 7-11/2 * * * cmd
      13.  0 6 * * * cmd
      14.  0 4 * * 6 cmd
      15.  5 4 * * 6 cmd
      16.  40 8 * * * cmd
      17.  31 10/2 * * * cmd
      18.  0 2 * * 1-5 cmd
      19.  0 8,9 * * 1-5 cmd
      20.  0 10,16 * * * cmd