Linux 中的 Crontab 解释[附示例]
了解 Linux 中 crontab 的概念。了解如何设置 cron 作业以在预定义时间自动运行脚本和命令。
crontab 用于自动执行 Linux 系统上的所有类型的任务。对于有抱负的系统管理员来说,这是一项特别重要的技能。如果您是初学者,入门可能会有些困难。语法与大多数其他命令不同。因此,在向您展示一些用途之前,本课程将包含更多背景信息。
不要被 crontab 吓倒
对我来说,作为一个新手,Crontab 是最令人生畏的 Linux 概念之一。当我接触“crontab”时,我只使用了几天命令行,几乎不了解如何使用“ls”和“cd”等基本文件导航命令。
我之所以提出我个人的学习历史,是因为我预计很多新的 Linux 用户在看到“crontab”的独特语法时可能会感到同样不知所措。不过,我可以向您保证,一旦您了解了它的工作原理,事情就没有那么复杂了。
您将在本指南中学到什么
我想简单介绍一下 crontab 涉及的一些概念,以便于理解。我的目标是将这些概念置于上下文中并说明它们之间的关系。
Cron 概念快速介绍
为您的用户帐户设置 crontab 访问权限
使用 cronjobs 处理错误
创建定时任务
快速介绍关键 cron 概念
让我首先向您介绍一些有关“cron”的基本概念。
Cron、Crontab 和 Cron Job 之间的区别
直观地观察事物有助于更快地理解新主题。以下是这三个主题通常如何相互作用的细分。然后我将更详细地描述每一个。
Element | Linux Name | Meaning |
---|---|---|
Daemon | ‘crond’ | Pronounced “demon” or “day-mon”. These are Linux background system processes. |
Table | ‘crontab’ | You write rows to this table when entering a crontab command. Each ‘*’ asterisk represents a segment of time and a corresponding column in each row. |
Job | Cron Job | The specific task to be performed described in a row, paired with its designated time id |
计划表
Crontab 代表 Cron 表。这是一个 Linux 系统文件,它创建一个类似表的结构,其中字段由空格分隔。用户可以通过为每个字段(星号)分配值来填充表。
在整篇文章中,我可能会使用不同的语言来描述这个想法。需要明确的是,字段、单元格、列等都指的是同一事物。如果有帮助的话,您可以将 crontab 想象成一个迷你数据库。
计划任务
如果您不熟悉数据库,您可以想象空白 Excel 文件中的单元格。不管怎样,对于这个类比,每个星号代表一个列,其含义由其标题定义。最后一列将是对命令或脚本的调用。每个完整的行都可以被视为一个单独的作业。这些通常被称为“cron 作业”,尽管作业、任务等都是可以互换的术语。
Cron 守护进程
我们已经讨论过该表以及如何在其中填充工作。但是,这些工作如何执行?一个称为守护进程的系统进程在我们的 Linux 机器的后台运行。
许多不同的服务都有守护进程。这些通常通过在服务名称后添加“d”来命名。
当然,cron 守护进程被称为“crond”。我们不需要执行任何操作来执行该守护进程,但如果您认为该命令无法正常工作,您可以使用 ps 命令来验证“crond”是否正在运行。
ps aux | grep crond
此命令将搜索所有用户的当前进程并返回“crond”的任何实例。
christopher@pop-os:~$ ps ux | grep crond
christo+ 8942 0.0 0.0 18612 840 pts/0 S+ 02:16 0:00 grep --color=auto crond
我可以看到守护进程正在为我的用户帐户运行。我已经知道这一点,因为我整天都在用输出填充文件。
了解 crontab 语法
现在您已经对 cron 的工作原理有了一个模糊的了解,让我们看看使用 crontab 的语法。如果您能在脑海中将这些信息想象成一张表格,我希望您不会那么困惑。
crontab [options]
* * * * * <command>
OR
* * * * * <path/to/script>
我保证,一旦我们启动并运行我们自己的示例,这将对您有所帮助。让我们再次回顾一下 cron 作业的语法。
正如您所看到的,crontab 语法有 5 个星号。以下是每个星号代表的含义:
1st | 2nd | 3rd | 4th | 5th | |
---|---|---|---|---|---|
* | * | * | * | * | |
ID | Minute | Hour | Day-Date | Month | Day Name |
Values | 0-59 | 0 -23 | 1-31 | 1-12 | 0-6 |
注意:日期名称 0-6 从星期日开始。
为了安排任务,您可以将适当的星号替换为您想要的值。
让我们快速练习一下。如果您有如下所示的 crontab,您认为该作业何时运行?
0 0 * * 0
问:如果这样设置作业,命令什么时候运行?
A. 从周一到周六每小时
B.周日的每一分钟
C.仅限周一至周六午夜
D.仅限周日午夜
这里的答案是 D。每周日 00:00 [午夜]运行“命令”。
为您的用户帐户设置 crontab 访问
Crontab 是特定于用户的。你已经触及了一点。如果您认为您以前可能已经使用过 crontab,则可以使用 crontab -l 进行检查。
christopher@pop-os:~$ crontab -l
no crontab for christopher
christopher@pop-os:~$ crontab -e
no crontab for christopher - using an empty one
Select an editor. To change later, run 'select-editor'.
1. /bin/nano <---- easiest
2. /usr/bin/code
3. /bin/ed
Choose 1-3 [1]: 1
当我运行这个命令时,你可以看到我的系统上没有 crontab。
由于我还没有创建 crontab,当我使用 -e
编辑表时,它会提示我选择我喜欢的文本编辑器。 Nano 被建议为最容易使用的程序。您可以使用任何命令行文本编辑器,例如 Vim 或 Emacs。这真的取决于你。
如果一开始你没有成功,Sudo
如果您尝试使用 crontab -e 命令但没有得到此结果,则您可能没有创建该表的用户权限。如果您有 sudo 访问权限,则可以使用 sudo 设置 crontab。
sudo crontab -e <your_username>
您的系统会自动将您的 crontab 加载到正确的目的地,该目的地可能会因发行版而异,但通常位于 /var/spool/cron/crontabs 等目录中。不要尝试在此处编辑文件。
如果 cron 作业遇到错误会发生什么?
默认行为是通过电子邮件发送其输出。此功能专为管理员设计,他们可以自动将日志发送到网络域上的“本地”电子邮件。
如果您有邮件服务器,您可以自行设置。还有一些方法可以自动将电子邮件输出到 GMail 或类似服务。但是,这些方法超出了本文的范围。
相反,我们将研究解决该错误的两种常见方法。
1) 将输出发送到文件
您可以指定要发送此类输出的文件,然后使用 >>
重定向输出。
使用 >>
会将信息附加到现有文件,而单个 >
符号将覆盖该文件。如果您想要维护一个经常更新记录的大型日志文件,了解这一点很重要。如果文件不存在,两者都会自动创建该文件。
计划任务示例:
0 * * * * echo "Linux is Cool!" >> ~/crontab_log.txt
2)使用/dev/null
这将通过实质上删除数据来绕过电子邮件选项。标准错误(‘2’)和标准输出(‘1’)都发送到 /dev/null 文件。
0 0 * * * echo "Why are you silencing me every night at midnight?" > /dev/null 2>&1
您可能已经注意到我在示例中使用了 echo 命令。这没有什么特别的原因,但它可以轻松验证更改并“检查您的工作”。
如果您做过一些编程,您可能已经使用过打印命令来测试您的逻辑。这是同一个概念。
让我们尝试设置我们自己的 cron 作业。如果您已经在“一起玩”,那就太好了。如果没有,现在是时候准备好终端并享受一些乐趣了。
Crontab 示例:调度命令和脚本
我在解释输出如何路由时向您展示了几个示例。这些对你来说有意义吗?
让我来看看第一个例子。
Minute | Hour | Day-Date | Month | Day Name | Command |
---|---|---|---|---|---|
0 | * | * | * | * | echo “Linux is Cool!” >> ~/crontab_log.txt |
将分钟值设置为“0”意味着该命令将每小时运行一次。
高级工作安排
您可以一次编辑多个值。如果需要,您可以将所有 5 个星号替换为规格。
Minute | Hour | Day-Date | Month | Day Name | Command |
---|---|---|---|---|---|
*/5 | 3-6 | */5 | */2 | 0,6 | echo “Linux is Cool!” >> ~/crontab_log.txt |
知道这个说什么吗?为了本教程的目的,我让这项工作变得特别混乱。在“野外”拥有如此多参数的东西是不寻常的,但让我们看看你是否能破译它。对于这样的事情,我喜欢在各个领域进行逆向工作。
让我们一起尝试一下:
Field | Value | Meaning |
---|---|---|
Day Name | 0,6 | Saturday and Sunday |
Month | */2 | Every month that is divisible by 2 (even) months. |
Day Date | * | Every Date |
Hour | 3-6 | Between 3 and 6 AM |
Minutes | */5 | Every 5 Minutes |
用通俗易懂的语言来说:
因此,每隔一个月的周末,无论日期如何,此命令都会在凌晨 3 点到 6 点之间每 5 分钟运行一次。
哇,这很复杂。如果你能够遵循这一点,那么你就准备好与其中最好的人一起执行计划任务了。
编写一个简单的 cron 自动化脚本来备份文件
到目前为止,您编写的 cron 作业只做了一件事。这可能很有用,但也许您想要执行多项任务。
幸运的是,这不仅是可能的,而且非常容易。如果您还记得原始语法示例,您还可以使用脚本的路径。
这也不限于 bash,如果需要,您还可以实现使用 Python 或 Perl 的脚本。
我们的目标是什么?
工作将在每晚凌晨 3 点处理
将 /Documents 文件夹备份到 zip 文件
生成一个文本文件,其中包含目录中所有内容的列表
创建一个存档文件夹,将我们的备份和文本文件克隆到具有当前日期的子文件夹中
our_backup_script.sh
#! /bin/bash
DATE=$(date +%d-%m-%Y)
# Date in format DAY##-MONTH##-YEAR####
mkdir -p ~/archive/$DATE
# create a folder for today's date in the archive, if archive doesn't exist, make archive
ls -al ~/Documents > ~/archive/$DATE/contents.txt
# create a text file listing the contents of the documents folder
cd ~/ && tar -cpzf $DATE.docs.backup.gz Documents/*
# change to parent directory to tar /Documents folder
cp ~/$DATE.docs.backup.gz ~/archive/$DATE/documents_archive.gz
# one .gz file is left in the home directory, a clone is sent to our archive under it's date
christopher@pop-os:~$ ls
Desktop Downloads Music Pictures Public Videos
Documents ENV our_backup_script.sh projects Templates 'VirtualBox VMs'
christopher@pop-os:~$ bash our_backup_script.sh
christopher@pop-os:~$ ls
25-11-2019.docs.backup.gz Documents Music projects Videos
archive Downloads our_backup_script.sh Public 'VirtualBox VMs'
Desktop ENV Pictures Templates
christopher@pop-os:~$ ls archive/25-11-2019/
contents.all_files.txt documents_archive.gz
剩下要做的就是让这个脚本成为一个 cron 作业。
crontab -e
并在其中添加以下内容:
0 3 * * * bash ~/our_backup_script.sh
你的成功了吗?我的是。事实上,我非常喜欢这个想法,以至于我可以将其保留为每日备份。我要做的一项修改是将我的存档移动到我的计算机上与云存储同步的文件夹中。
以下是您所学知识的快速总结:
在 Linux 中调度作业的另一种方法是使用 at 命令。您可能也有兴趣了解这一点。
您对想要创建的脚本有什么想法吗?这篇文章是否帮助您更好地理解 crontab ?在评论中与我们分享。