如何通过脚本创建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 -l和echo命令写出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。