通过示例了解 Linux 中的 Crontab
crontab 用于自动执行 Linux 系统上的所有类型的任务。对于有志于成为系统管理员的人来说,这是一项特别重要的技能。如果您是初学者,入门可能会有些困难。它的语法与大多数其他命令不同。因此,在向您展示一些用途之前,本课将包含一些背景信息。
不要被 crontab 吓倒
对于我这个新手来说,Crontab 是最令人生畏的 Linux 概念之一。在接触“crontab”时,我才刚使用命令行几天,几乎不懂如何使用“ls”和“cd”等基本文件导航命令。
我之所以提到我的个人学习经历,是因为我预计很多 Linux 新用户在看到“crontab”的独特语法时可能会感到同样不知所措。不过我可以向你保证,一旦你理解了它的工作原理,它就不会那么复杂。
您将在本指南中学到什么
我想快速介绍一下与 crontab 相关的一些概念,以便于理解。我的目标是将这些概念置于上下文中,并说明它们之间的关系。
- Cron 概念简介
- 为您的用户帐户设置 Crontab 访问
- 使用 cronjobs 处理错误
- 创建 cronjobs
快速介绍关键的 cron 概念
首先让我向您介绍一些有关“cron”的基本概念。
Cron,Crontab 和 Cron Job 之间的区别
直观地看事物有助于更快地理解新主题。以下是这三个主题通常如何相互作用的细分。然后我将更详细地描述每个主题。
元素 | Linux 名称 | 意义 |
---|---|---|
守护进程 | ‘crond’ | 发音为“demon”或“day-mon”。这些是 Linux 后台系统进程。 |
桌子 | ‘crontab’ | 输入 crontab 命令时,您会将行写入此表。每个“*”星号代表一段时间段以及每行中的对应列。 |
工作 | 计划任务 | 一行中描述要执行的具体任务,并与其指定的时间 ID 配对 |
Cron 表
Crontab 代表 Cron Table。这是一个 Linux 系统文件,它创建了一个表格结构,其中字段由空格分隔。用户可以通过为每个字段(星号)分配值来填充表格。
在整个文章中,我可能会使用不同的语言来描述这个想法。要清楚,字段、单元格、列等都指的是同一件事。如果有帮助的话,你可以把你的 crontab 想象成一个迷你数据库。
Cron 任务
如果您不熟悉数据库,可以想象一下空白 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 个星号。以下是每个星号代表的含义:
第一 | 第二 | 第三 | 第四 | 第五 | |
---|---|---|---|---|---|
* | * | * | * | * | |
ID | 分钟 | 小时 | 星期日历型 | 月 | 星期名称 |
价值观 | 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)将输出发送到文件
您可以指定一个文件来发送此类输出,然后用于>>
重定向输出。
使用>>
会将信息附加到现有文件,而单个>
符号会覆盖文件。如果您要维护一个频繁更新记录的大型日志文件,这一点很重要。如果文件不存在,两者都会自动创建文件。
Cron Job示例:
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 示例:调度命令和脚本
我在解释输出如何路由时向您展示了几个示例。您理解了吗?
让我来介绍一下第一个例子。
分钟 | 小时 | 星期日历型 | 月 | 星期名称 | 命令 |
---|---|---|---|---|---|
0 | * | * | * | * | 回显“Linux 很酷!”>> ~/crontab_log.txt |
将分钟值设置为“0”意味着该命令将每小时整点运行一次。
高级作业计划
您可以一次编辑多个值。如果您愿意,可以将所有 5 个星号替换为规范。
分钟 | 小时 | 星期日历型 | 月 | 星期名称 | 命令 |
---|---|---|---|---|---|
*/5 | 3-6 | * | */2 | 0,6 | 回显“Linux 很酷!”>> ~/crontab_log.txt |
知道这句是什么意思吗?为了本教程的目的,我把这个工作弄得特别令人困惑。在“野外”有这么多参数的东西是不寻常的,但让我们看看你是否能破译它。对于这样的事情,我喜欢通过字段反向工作。
我们一起尝试一下:
场地 | 价值 | 意义 |
---|---|---|
星期名称 | 0,6 | 周六和周日 |
月 | */2 | 每个能被 2(偶数)月份整除的月份。 |
星期日历 | * | 每次约会 |
小时 | 3-6 | 凌晨 3 点至 6 点之间 |
分钟 | */5 | 每 5 分钟 |
用通俗的语言来说:
因此每隔一个月,在周末,无论日期如何,此命令都会在凌晨 3 点到早上 6 点之间每 5 分钟运行一次。
哇,这太复杂了。如果你能理解,那么你就可以和他们中最好的人一起完成 cron 任务了。
编写一个简单的 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?请在评论中与我们分享。