一.学习的内容
经验丰富的系统运维工程师可以使得Linux在无须人为介入的情况下,在指定的时间段自动启用或停止某些服务或命令,从而实现运维的自动化。计划任务分为一次性计划任务与长期性计划任务,大家可以按照如下方式理解。
一次性计划任务:今晚23:30重启网站服务。
长期性计划任务:每周一的凌晨3:25把/home/wwwroot目录打包备份为backup.tar.gz。
一次性计划任务只执行一次,一般用于临时的工作需求。可以用at命令实现这种功能,只需要写成 “at时间” 的形式就行。如果想要查看已设置好但还未执行的一次性计划任务,可以使用 at -l命令;要想将其删除,可以使用 “atrm 任务序号” 。at命令中的参数及其作用如表1所示。
参数 | 作用 |
-f | 指定包含命令的任务文件 |
-q | 指定新任务名称 |
-l | 显示待执行任务列表 |
-d | 删除指定待执行任务 |
-m | 任务执行后给用户发邮件 |
在使用at命令来设置一次性计划任务时,默认采用的是交互式方法。例如,使用下述命令将系统设置为在今晚21:15自动输出当前工作目录。输入pwd后,按ctrl + d 结束输入。

看到warning提醒信息不要慌,at命令只是在告诉我们接下来的任务将由sh解释器负责执行。这与此前学习的Bash解释器基本一致,不需要有额外的操作。
下面使用 at -l 命令查看刚才创建的计划任务。

可以把前面学习的管道符(任意门)放到两条命令之间,让at命令接收前面echo命令的输出信息,以达到通过非交互式的方式创建计划一次性任务的目的。

可以使用 atrm命令 轻松删除其中一条,或者使用 at -d 命令:

这里还有一种特殊场景—把计划任务写入Shell脚本中,当用户激活该脚本后再开始倒计时执行,而不是像上面那样在固定的时间(“at 时间”命令)进行。一般我们会使用 “at now +2 MINUTE”的方式进行操作,这表示2分钟(MINUTE)后执行这个任务,也可以将其替代成小时(HOUR)、日(DAY)、月(MONTH)等词汇:

下面时运行这个shell脚本的输出界面,可以看到创建了一个十分钟后执 ls 的计划任务。

下面使用 -f 参数,直接从test文本文件中读取命令,貌似比 echo + 管道符 更强大。

还有些时候,我们希望Linux系统能够周期性地、有规律地执行某些具体的任务,那么Linux系统中默认启用的crond服务简直再适合不过了。创建、编辑计划任务的命令为crontab -e,查看当前计划任务的命令为crontab -l,删除某条计划任务的命令为crontab -r。另外,如果您是以管理员的身份登录的系统,还可以在crontab命令中加上-u参数来编辑他人的计划任务。crontab命令中的参数及其作用如表2所示。
参数 | 作用 |
-e | 编辑计划任务 |
-u | 指定用户名称 |
-l | 列出任务列表 |
-r | 删除计划任务 |
“分 时 日 月 星期 命令”,这是使用crond服务设置任务的参数格式(其格式见表3)。需要注意的是,如果有些字段没有被设置,则需要使用星号(*)占位,如图8所示。
字段 | 说明 |
分钟 | 取值为0~59的整数 |
小时 | 取值为0~23的任意整数 |
日期 | 取值为1~31的任意整数 |
月份 | 取值为1~12的任意整数 |
星期 | 取值为0~7的任意整数,其中0与7均为星期日 |
命令 | 要执行的命令或程序脚本 |

假设在每周一、三、五的 21:59,都需要使用tar命令把某个网站的数据目录进行打包处理,使其作为一个备份文件。我们可以使用 crontab -e 命令来创建计划任务,为自己创建计划任务时无须使用 -u 参数。crontab –e 命令的具体实现效果和 crontab -l 命令的结果如下所示:

等待执行时间的到来,使用 ls -l 命令查看任务是否执行了。或者使用ls 命令查看有没有backup.tar.gz 文件。

下图是使用 crontab -e 命令后进入的界面,其实就是vim 编辑器的界面,在这里面输入正确的参数格式即可。

需要说明的是,除了用逗号(,)来分别表示多个时间段,例如“8,9,12”表示8月、9月和12月。还可以用减号(-)来表示一段连续的时间周期(例如字段“日”的取值为“12-15”,则表示每月的12~15日)。
如果在crond服务中需要同时包含多条计划任务的命令语句,应每行仅写一条。例如我们再添加一条计划任务,它的功能是每周一至周五的22:09分都会输出 i love Linux 。尤其需要注意的是,在crond服务的计划任务参数中,所有命令一定要用绝对路径的方式来写。如果不知道绝对路径,请用whereis命令进行查询。

删除crond计划任务则非常简单,直接使用crontab -e命令进入编辑界面,删除里面的文本信息即可。也可以使用crontab -r命令直接进行删除:

总结一下使用计划服务的注意事项:
1、在crond服务的配置参数中,一般会像Shell脚本那样以#号开头写上注释信息,这样在日后回顾这段命令代码时可以快速了解其功能、需求以及编写人员等重要信息。
2、计划任务中的“分”字段必须有数值,绝对不能为空或是*号,而“日”和“星期”字段不能同时使用,否则就会发生冲突。
二.本次学习遇到的问题
1、计划任务执行完后,它们的输出跑哪了?
2、在crond计划任务中,所有命令都要写绝对路径,那内部命令怎么办?找不到它的绝对路径。
三、问题的答案及解决办法
1、
在 cron 任务中运行命令时,命令的输出默认情况下并不会显示在屏幕上。cron 任务是在后台静默运行的,并且通常不会将输出发送到终端。所以,即使你在 cron 任务中运行了 pwd 命令,也不会直接在屏幕上看到输出。要查看 cron 任务的输出,你可以选择:
将输出重定向到文件:在 cron 任务中将输出重定向到文件,这样你就可以在文件中查看命令的输出。例如:

等待命令执行时间的到来,之后使用cat 命令查看,发现确实输出到了指定文件。

在使用 at 命令时,默认情况下也是不会将输出发送到终端的。和 cron 任务类似,`at` 任务也是在后台运行的,通常不会直接将输出显示在屏幕上。要查看 `at` 任务的输出,你也可以采取类似的方法。


2、
在cron任务中,内置命令需要使用类似于bash -c的方法来执行,而外部命令则可以直接使用绝对路径。
内置命令(例如cd、echo等)是shell的一部分,它们通常不是独立的可执行文件,因此在cron任务中需要使用shell解释器来执行它们。
而外部命令(例如/bin/ls、/usr/bin/python等)是作为独立的可执行文件存在的,它们可以直接通过路径执行,因此在cron任务中可以直接使用它们的绝对路径来执行。
补:
at 命令
crontab 命令