Contents

如何通过脚本创建crontab

1. 概述

我们可能会使用cron作为我们软件设计的一部分,并希望在多台机器上安装该软件。要生成安装脚本,我们需要知道如何通过脚本添加我们的cron作业。

在本教程中,我们将了解如何在几个地方安装cron作业,以及如何编写脚本来为我们执行此操作。

2. 安装crontab

系统中有两个不同的crontab 文件:

  • 用户crontab文件
  • 系统crontab文件

用户crontab文件中的作业只会为特定用户运行。因此,如果我们需要为所有用户运行该作业,我们应该将其添加到系统crontab中。

2.1. 示例Cron作业

让我们创建一个示例脚本 - job.sh

#!/bin/bash
echo `date +"%Y-%M-%d %T"`" - Hello Blogdemo" >> /home/blogdemo/log.txt

我们可以随时检查log.txt以查看我们的计划作业是否已运行。

2.2. 将作业添加到用户crontab

要了解用户crontab,让我们手动将脚本添加到其中:

$ crontab -e

此命令将打开一个编辑器来编辑现有用户crontab。让我们附加我们的cron表达式:

30 0 * * * /home/blogdemo/job.sh

这会安排脚本在每天午夜后 30 分钟运行。我们已经在我们的主目录 - /home/blogdemo中创建了作业。 我们还需要确保当前用户对该脚本具有执行权限。所以,让我们使用chmod 命令来添加它们:

$ chmod +x /home/blogdemo/job.sh

现在我们的job.sh已经安排好了,并且每天都会运行。我们可以通过检查log.txt文件来测试这一点。

2.3. 将作业添加到系统crontab

要了解系统crontab,我们还要手动添加这个脚本:

$ sudo nano /etc/crontab

系统crontab文件保存在*/etc/crontab*中。让我们附加以下行:

30 0 * * * root /home/blogdemo/job.sh

我们应该注意,我们需要指定root用户名。这是因为系统 cron 中的作业是系统作业,将由root用户运行。

3. 将作业添加到用户crontab的脚本

现在让我们尝试自动化该过程以添加到用户 crontab

3.1. 将新文件安装到crontab

让我们首先创建一个新的脚本文件:

$ touch /home/blogdemo/myScript.sh

我们的脚本要做的第一件事是复制所有当前作业:

#!/bin/bash
crontab -l > crontab_new 

我们现在在 crontab_new文件中拥有所有以前的作业。这意味着我们可以将我们的新作业附加到它,然后使用编辑后的文件作为crontab命令的输入参数来重写crontab

echo "30 0 * * * /home/blogdemo/job.sh" >> crontab_new
crontab crontab_new

由于crontab_new文件是临时文件,我们可以将其删除:

rm crontab_new

我们还必须记住使用chmod +x使脚本可执行:

$ chmod +x /home/blogdemo/myScript.sh
$ ./myScript.sh

这种方法效果很好,尽管它确实需要使用临时文件。让我们看看我们是否可以进一步优化它。

3.2. 使用管道优化之前的脚本

我们之前的脚本依赖于一个临时文件,因此必须对其进行整理。它也没有检查是否已经安装了cron条目,因此,如果多次运行,它可能会安装重复的条目。

我们可以通过使用基于管道的脚本来解决这两个问题:

#!/bin/bash
(crontab -l; echo "30 0 * * * /home/blogdemo/job.sh") | sort -u | crontab -

和以前一样,crontab -lecho命令写出crontab的前几行以及新条目。这些通过 sort 命令传送以删除重复的行。sort中的*-u*选项用于仅保留唯一行。

其结果通过管道传送到crontab命令,该命令用新条目重写crontab文件。

但是,我们应该知道,使用sort将完全重新排序文件,包括任何注释。 sort -u在脚本中很容易理解,但我们可以使用**awk 实现破坏性较小的重复数据删除**:

#!/bin/bash
(crontab -l; echo "30 0 * * * /home/blogdemo/job.sh")|awk '!x[$0]++'|crontab -

这将从 crontab中删除所有重复项而不对其进行排序。

4. 将作业添加到系统Cron的脚本

现在让我们为系统cron作业编写一个安装脚本。

4.1. 使用系统crontab

首先,让我们创建一个新脚本:

$ touch /home/blogdemo/myScript2.sh

系统计划行的语法类似于用户计划。我们只需要在计划行中指定root用户名:

#!/bin/bash
sudo /bin/bash -c 'echo "30 0 * * * root /home/blogdemo/job.sh" >> /etc/crontab'

我们在echo之前使用sudo /bin/bash ,因为用户需要以root用户身份访问echo和重定向。否则,我们将收到权限被拒绝错误,因为只有echo将由root运行,并且重定向将使用当前用户的权限进行。-c选项告诉 bash将单引号中的命令作为字符串获取并在 shell 中运行。

我们应该注意到,与之前使用的 crontab命令相比,这是简单的文件操作。如果我们想避免重复条目,我们可以添加类似的过滤器,如 sort或 awk

4.2. 使用*/etc/cron.d*目录

除了*/etc/crontab路径之外,cron还将 /etc/cron.d目录中的所有文件视为系统作业。因此,我们也可以将调度行放在/etc/cron.d*目录中的新文件中。

现在让我们创建另一个脚本来将作业添加到cron.d目录,作为*/etc/crontab*文件的替代:

$ touch /home/blogdemo/myScript3.sh

我们需要将 schedule 行放在cron.d目录中的一个新文件中——我们将调用我们的文件schedule。请注意,在*/etc/cron.d中,某些文件名被视为无效。例如,如果我们选择schedule.sh*作为文件名,它将被跳过,因为文件名不应该有任何扩展名

#!/bin/bash
sudo touch /etc/cron.d/schedule

cron.d目录及其子目录通常由系统服务使用,只有root用户才能访问这些目录。此外,/etc/cron.d中的文件必须归root所有。所以,我们需要使用sudo

现在让我们将计划行放在schedule文件中并更改权限:

sudo echo "30 0 * * * root /home/blogdemo/job.sh" > /etc/cron.d/schedule
sudo chmod 600 /etc/cron.d/schedule

请注意,我们将文件的权限更改为 600。这是因为/etc/cron.d*中的文件不能被 group 或 other 写入*。否则,它们将被忽略。此外,/etc/cron.d下的计划文件不需要是可执行的。所以,我们不需要权限 700。