如何通过脚本创建crontab

gau*_*rav 131 linux shell ubuntu cron crontab

我需要通过运行的脚本添加一个cron作业来设置服务器.我目前正在使用Ubuntu.我可以使用,crontab -e但会打开一个编辑器来编辑当前的crontab.我想以编程方式执行此操作.

有可能这样做吗?

Joe*_*nte 326

这是一个不使用/要求新作业在文件中的单行程序:

(crontab -l 2>/dev/null; echo "*/5 * * * * /path/to/job -with args") | crontab -
Run Code Online (Sandbox Code Playgroud)

2>/dev/null很重要,这样no crontab for username如果当前没有crontab条目,您就不会收到某些*nix产生的消息.

  • 这应该是公认的答案.现在只需要一种方法来检查我打算添加的单线是否已经存在...... (12认同)
  • ...哦等等,这是在我用脚本添加它之前如何检查我的用户的crontab中是否有东西:http://stackoverflow.com/a/14451184/3686125 (7认同)
  • 我发现这是删除现有的crontab条目,我还需要使用不同的用户(root),因此我使用以下内容来维护现有条目:`echo -e"$(sudo crontab -u root -l)\n*****echo hello> /home/danny/temp.log 2>&1"| sudo crontab -u root -`希望这有助于某人 (6认同)
  • 如果此脚本旨在作为重复并修改现有 cron 任务的命令,则最好替换 crontab 中的现有行。可以使用多个标记来控制不同的 cron 任务(control-marker-1、control-marker-2 等...): (crontab -l 2>/dev/null | grep -v control-marker-1; echo '*/5 * * * * /path/to/job -with args #control-marker-1') | crontab - (3认同)

Pau*_*ce. 55

对于用户crontabs(包括root),您可以执行以下操作:

crontab -l -u user | cat - filename | crontab -u user -
Run Code Online (Sandbox Code Playgroud)

名为"filename"的文件包含要追加的项目.您也可以使用sed或使用其他工具进行文本操作cat.您应该使用该crontab命令而不是直接修改该文件.

类似的操作是:

{ crontab -l -u user; echo 'crontab spec'; } | crontab -u user -
Run Code Online (Sandbox Code Playgroud)

如果要修改或创建系统crontabs,则可以像处理普通文本文件一样对其进行操作.它们存储在/etc/cron.d,/etc/cron.hourly,/etc/cron.daily,/etc/cron.weekly,/etc/cron.monthly目录和文件/etc/crontab/etc/anacrontab.


小智 26

在Ubuntu和许多其他发行版中,您只需将文件放入/etc/cron.d包含带有有效crontab条目的单行的目录中即可.无需在现有文件中添加一行.

如果您只需要每天运行一些东西,只需将文件放入/etc/cron.daily.同样的,你也可以文件拖放到/etc/cron.hourly,/etc/cron.monthly/etc/cron.weekly.

  • 但你必须是root用户才能做到这一点. (5认同)

cle*_*oux 16

Crontab文件只是文本文件,因此可以像任何其他文本文件一样对待.该crontab命令的目的是使编辑crontab文件更安全.通过此命令编辑时,将检查文件是否存在错误,仅在没有错误时才保存.

crontab [path to file]可用于指定存储在文件中的crontab.就像crontab -e,这只会安装文件,如果它没有错误.

因此,脚本可以直接写入cron选项卡文件,也可以将它们写入临时文件并使用该crontab [path to temp file]命令加载它们.直接写入可以节省写入临时文件的时间,但也避免了安全检查.

  • 对于像我这样的菜鸟,请注意,它是`crontab [文件路径]`..这绝对是我的最佳选择,因为它允许更清晰的代码。我使用crontab跟踪包裹并使用状态更改我的桌面墙纸。当我不希望收到包裹时,不需要每小时检查一次。这就是为什么我想要脚本自动编辑cron频率的原因。 (2认同)

小智 16

更简单的回答你的问题是:

echo "0 1 * * * /root/test.sh" | tee -a /var/spool/cron/root
Run Code Online (Sandbox Code Playgroud)

您可以在远程服务器上设置cronjobs,如下所示:

#!/bin/bash
servers="srv1 srv2 srv3 srv4 srv5"
for i in $servers
  do
  echo "0 1 * * * /root/test.sh" | ssh $i " tee -a /var/spool/cron/root"
done
Run Code Online (Sandbox Code Playgroud)

在Linux中,crontab文件的默认位置是/var/spool/cron/.在这里,您可以找到crontab所有用户的文件.您只需将cronjob条目附加到相应用户的文件即可.在上面的示例中,root用户的crontab文件附加了一个cronjob,/root/test.sh每天凌晨1点运行.


小智 13

Cron作业通常存储在每个用户文件下 /var/spool/cron

最简单的事情可能就是创建一个配置了作业的文本文件,然后将其复制到cron spool文件夹并确保它具有正确的权限.

  • 向下滚动查看真实答案. (38认同)
  • 直接在/ var/spool/cron中修改文件是不受欢迎的.事实上,如果您查看那里的文件,它们通常会包含警告,例如"请勿编辑此文件"作为第一行. (19认同)
  • @Jared虽然我完全同意这个想法,但说"不赞成"并没有多大帮助.而是告诉应该编辑哪个_other_文件(如果有),或者解释手动编辑文件的风险.我打算通过自动命令行创建一些cron作业,如果编辑这个文件是唯一的选择,并且没有明显的副作用,我不明白为什么我不应该使用它. (11认同)
  • 我采用这种方法感到遗憾。在RHEL上,目录/ var / spool / cron不是世界可执行文件,因此用户无法遍历该目录并手动编辑其文件。如果使/ var / spool / cron world可执行文件,则友好的本地sysadmin会对您发火,如果重新安装或更新了cronie软件包,则权限更改可能会被覆盖。 (2认同)

Dir*_*tel 6

那么/etc/crontab只是一个 ascii 文件,所以最简单的就是

 echo "*/15 * * * *   root     date" >> /etc/crontab
Run Code Online (Sandbox Code Playgroud)

这将添加一个工作,该工作将每 15 分钟向您发送电子邮件。根据口味进行调整,并通过grep或其他方式测试是否已添加该行以使您的脚本具有幂等性。

在 Ubuntu 等上,您还可以删除/etc/cron.*更容易执行和测试的文件---此外,您不会弄乱(系统)配置文件,例如/etc/crontab.


use*_*840 6

作为对这些建议的更正crontab -l | crontab -:并非在所有系统上都有效。例如,我不得不在数十台运行旧版本SUSE的服务器上的根crontab中添加作业(不要问为什么)。旧的SUSE会将注释行添加到的输出之前crontab -l,从而使其成为crontab -l | crontab -非幂等的(Debian在crontab联机帮助页中识别了此问题,并对其Vixie Cron版本进行了修补以更改的默认行为crontab -l)。

要在crontab -l添加注释的系统上以编程方式编辑crontabs ,可以尝试以下操作:

EDITOR=cat crontab -e > old_crontab; cat old_crontab new_job | crontab -

EDITOR=cat告诉crontab cat用作编辑器(不是通常的默认vi),该编辑器不会更改文件,而是将其复制到stdout。如果crontab -期望输入的格式与crontab -e输出的格式不同,这可能仍然会失败。不要尝试更换最后crontab -crontab -e-这是行不通的。


Far*_*ria 6

(我没有足够的声誉来发表评论,所以我在这里添加一个答案:随时在他的答案旁边添加它作为评论)

Joe Casadonte的单行代码是完美的,除非您使用运行set -e,即,如果脚本设置为因错误而失败,并且还没有cronjobs。在这种情况下,单行将不会创建cronjob,但不会停止脚本。无声的失败可能会引起很大的误导。

原因是crontab -l返回时返回了一个1返回码,导致后续命令(echo)不被执行...因此,不会创建cronjob。但是由于它们是作为子进程执行的(由于括号),因此它们不会停止脚本。

(有趣的是,如果再次运行相同的命令,它将起作用:一旦执行crontab -一次,crontab -l仍然不输出任何内容,但不再返回错误(不再收到该no crontab for <user>消息)。因此echo执行后续命令并创建crontab)

无论如何,如果使用运行set -e,则该行必须是:

(crontab -l 2>/dev/null || true; echo "*/5 * * * * /path/to/job -with args") | crontab -
Run Code Online (Sandbox Code Playgroud)