如何在没有交互式编辑器的情况下使用 Bash 自动创建 cron 作业?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/878600/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 18:11:45  来源:igfitidea点击:

How to create a cron job using Bash automatically without the interactive editor?

bashshellcron

提问by Raúl Roa

Does crontab have an argument for creating cron jobs without using the editor (crontab -e). If so, What would be the code create a cronjob from a Bash script?

crontab 是否具有在不使用编辑器的情况下创建 cron 作业的参数 (crontab -e)。如果是这样,从 Bash 脚本创建 cronjob 的代码是什么?

回答by dogbane

You can add to the crontab as follows:

您可以按如下方式添加到 crontab:

#write out current crontab
crontab -l > mycron
#echo new cron into cron file
echo "00 09 * * 1-5 echo hello" >> mycron
#install new cron file
crontab mycron
rm mycron


Cron line explaination

定时线说明

* * * * * "command to be executed"
- - - - -
| | | | |
| | | | ----- Day of week (0 - 7) (Sunday=0 or 7)
| | | ------- Month (1 - 12)
| | --------- Day of month (1 - 31)
| ----------- Hour (0 - 23)
------------- Minute (0 - 59)

Source nixCraft.

来源nixCraft

回答by TheBonsai

You may be able to do it on-the-fly

您可以即时完成

crontab -l | { cat; echo "0 0 0 0 0 some entry"; } | crontab -

crontab -llists the current crontab jobs, catprints it, echoprints the new command and crontab -adds all the printed stuff into the crontab file. You can see the effect by doing a new crontab -l.

crontab -l列出当前的 crontab 作业,cat打印它,echo打印新命令crontab -并将所有打印的内容添加到 crontab 文件中。您可以通过执行 new 来查看效果crontab -l

回答by MoonCactus

This shorter one requires no temporary file, it is immune to multiple insertions, and it lets you change the schedule of an existing entry.

这个较短的不需要临时文件,它不受多次插入的影响,并且可以让您更改现有条目的时间表。

Say you have these:

假设你有这些:

croncmd="/home/me/myfunction myargs > /home/me/myfunction.log 2>&1"
cronjob="0 */15 * * * $croncmd"

To add it to the crontab, with no duplication:

要将其添加到 crontab,没有重复:

( crontab -l | grep -v -F "$croncmd" ; echo "$cronjob" ) | crontab -

To remove it from the crontab whatever its current schedule:

无论当前的时间表如何,要将其从 crontab 中删除:

( crontab -l | grep -v -F "$croncmd" ) | crontab -

Notes:

笔记:

  • grep -F matches the string literally, as we do not want to interpret it as a regular expression
  • We also ignore the time scheduling and only look for the command. This way; the schedule can be changed without the risk of adding a new line to the crontab
  • grep -F 从字面上匹配字符串,因为我们不想将其解释为正则表达式
  • 我们也忽略时间调度,只查找命令。这边走; 可以更改计划,而不会向 crontab 添加新行的风险

回答by Stoutie

Thanks everybody for your help. Piecing together what I found here and elsewhere I came up with this:

谢谢大家的帮助。将我在这里和其他地方发现的东西拼凑起来,我想出了这个:

The Code

编码

command="php $INSTALL/indefero/scripts/gitcron.php"
job="0 0 * * 0 $command"
cat <(fgrep -i -v "$command" <(crontab -l)) <(echo "$job") | crontab -

I couldn't figure out how to eliminate the need for the two variables without repeating myself.

我无法弄清楚如何在不重复自己的情况下消除对这两个变量的需求。

commandis obviously the command I want to schedule. jobtakes $commandand adds the scheduling data. I needed both variables separately in the line of code that does the work.

command显然是我想要安排的命令。job获取$command并添加调度数据。我需要在完成工作的代码行中分别使用这两个变量。

Details

细节

  1. Credit to duckyflip, I use this little redirect thingy (<(*command*)) to turn the output of crontab -linto input for the fgrepcommand.
  2. fgrepthen filters out any matches of $command(-voption), case-insensitive (-ioption).
  3. Again, the little redirect thingy (<(*command*)) is used to turn the result back into input for the catcommand.
  4. The catcommand also receives echo "$job"(self explanatory), again, through use of the redirect thingy (<(*command*)).
  5. So the filtered output from crontab -land the simple echo "$job", combined, are piped ('|') over to crontab -to finally be written.
  6. And they all lived happily ever after!
  1. 归功于duckyflip,我使用这个小小的重定向事物( <(*command*)) 将 的输出crontab -l转换为fgrep命令的输入。
  2. fgrep然后过滤掉$command( -voption)、不区分大小写 ( -ioption) 的任何匹配项。
  3. 同样,小重定向 ( <(*command*)) 用于将结果转换回cat命令的输入。
  4. cat命令还echo "$job"通过使用重定向事物 ( <(*command*))再次接收(不言自明)。
  5. 所以过滤后的输出crontab -l和简单的echo "$job"组合,通过管道('|')传递crontab -到最后被写入。
  6. 从此他们都过上了幸福的生活!

In a nutshell:

简而言之:

This line of code filters out any cron jobs that match the command, then writes out the remaining cron jobs with the new one, effectively acting like an "add" or "update" function. To use this, all you have to do is swap out the values for the commandand jobvariables.

这行代码过滤掉与命令匹配的任何 cron 作业,然后用新的 cron 作业写出剩余的 cron 作业,有效地充当“添加”或“更新”函数。要使用它,您所要做的就是交换commandjob变量的值。

回答by duckyflip

EDIT (fixed overwriting):

编辑(固定覆盖):

cat <(crontab -l) <(echo "1 2 3 4 5 scripty.sh") | crontab -

回答by Mike Mackintosh

There have been a lot of good answers around the use of crontab, but no mention of a simpler method, such as using cron.

关于 crontab 的使用已经有很多很好的答案,但是没有提到更简单的方法,例如使用cron.

Using cronwould take advantage of system files and directories located at /etc/crontab, /etc/cron.daily,weekly,hourlyor /etc/cron.d/:

使用cron将利用位于/etc/crontab,/etc/cron.daily,weekly,hourly或的系统文件和目录/etc/cron.d/

cat > /etc/cron.d/<job> << EOF
SHELL=/bin/bash 
PATH=/sbin:/bin:/usr/sbin:/usr/bin 
MAILTO=root HOME=/  
01 * * * * <user> <command>
EOF

In this above example, we created a file in /etc/cron.d/, provided the environment variables for the command to execute successfully, and provided the userfor the command, and the commanditself. This file should not be executable and the name should only contain alpha-numeric and hyphens (more details below).

在上面的示例中,我们在 中创建了一个文件/etc/cron.d/,为命令成功执行提供了环境变量,并user为命令提供了,以及它command本身。此文件不应是可执行文件,名称应仅包含字母数字和连字符(更多详细信息见下文)。

To give a thorough answer though, let's look at the differences between crontabvs cron/crond:

不过,为了给出一个彻底的答案,让我们看看crontabvs之间的区别cron/crond

crontab -- maintain tables for driving cron for individual users

For those who want to run the job in the context of their user on the system, using crontabmay make perfect sense.

对于那些想要在系统上的用户上下文中运行作业的人来说,使用crontab可能非常有意义。

cron -- daemon to execute scheduled commands

For those who use configuration management or want to manage jobs for other users, in which case we should use cron.

对于那些使用配置管理或想为其他用户管理作业的人,在这种情况下,我们应该使用cron.

A quick excerpt from the manpages gives you a few examples of what to and not to do:

联机帮助页的快速摘录为您提供了一些该做什么和不该做什么的示例:

/etc/crontab and the files in /etc/cron.d must be owned by root, and must not be group- or other-writable. In contrast to the spool area, the files under /etc/cron.d or the files under /etc/cron.hourly, /etc/cron.daily, /etc/cron.weekly and /etc/cron.monthly may also be symlinks, provided that both the symlink and the file it points to are owned by root. The files under /etc/cron.d do not need to be executable, while the files under /etc/cron.hourly, /etc/cron.daily, /etc/cron.weekly and /etc/cron.monthly do, as they are run by run-parts (see run-parts(8) for more information).

Source:http://manpages.ubuntu.com/manpages/trusty/man8/cron.8.html

/etc/crontab 和 /etc/cron.d 中的文件必须由 root 拥有,并且不能是组或其他可写的。与 spool 区相反,/etc/cron.d 下的文件或 /etc/cron.hourly、/etc/cron.daily、/etc/cron.weekly 和 /etc/cron.monthly 下的文件也可能是符号链接,前提是符号链接和它指向的文件都归 root 所有。/etc/cron.d 下的文件不需要可执行,而 /etc/cron.hourly、/etc/cron.daily、/etc/cron.weekly 和 /etc/cron.monthly 下的文件可以执行,如它们由运行部件运行(有关更多信息,请参阅运行部件(8))。

来源:http : //manpages.ubuntu.com/manpages/trusty/man8/cron.8.html

Managing crons in this manner is easier and more scalable from a system perspective, but will not always be the best solution.

从系统的角度来看,以这种方式管理 cron 更容易且更具可扩展性,但并不总是最好的解决方案。

回答by kvz

Chances are you are automating this, and you don't want a single job added twice. In that case use:

您可能正在自动化此操作,并且您不希望将单个作业添加两次。在这种情况下使用:

__cron="1 2 3 4 5 /root/bin/backup.sh"
cat <(crontab -l) |grep -v "${__cron}" <(echo "${__cron}")

This only works if you're using BASH. I'm not aware of the correct DASH (sh) syntax.

这仅在您使用 BASH 时有效。我不知道正确的 DASH ( sh) 语法。

Update:This doesn't work if the user doesn't have a crontab yet. A more reliable way would be:

更新:如果用户还没有 crontab,这将不起作用。更可靠的方法是:

(crontab -l ; echo "1 2 3 4 5 /root/bin/backup.sh") | sort - | uniq - | crontab - 

Alternatively, if your distro supports it, you could also use a separate file:

或者,如果您的发行版支持它,您也可以使用单独的文件:

echo "1 2 3 4 5 /root/bin/backup.sh" |sudo tee /etc/crond.d/backup

Found those in another SO question.

另一个 SO 问题中找到了那些。

回答by Gibbsoft

For a nice quick and dirty creation/replacement of a crontab from with a BASH script, I used this notation:

为了使用 BASH 脚本快速创建/替换 crontab,我使用了以下符号:

crontab <<EOF
00 09 * * 1-5 echo hello
EOF

回答by Gerald Schade

A variant which only edits crontab if the desired string is not found there:

如果在那里找不到所需的字符串,则仅编辑 crontab 的变体:

CMD="/sbin/modprobe fcpci"
JOB="@reboot $CMD"
TMPC="mycron"
grep "$CMD" -q <(crontab -l) || (crontab -l>"$TMPC"; echo "$JOB">>"$TMPC"; crontab "$TMPC")

回答by chuck

If you're using the Vixie Cron, e.g. on most Linux distributions, you can just put a file in /etc/cron.d with the individual cronjob.

如果您正在使用 Vixie Cron,例如在大多数 Linux 发行版上,您只需将一个文件放在 /etc/cron.d 中,并带有单独的 cronjob。

This only works for root of course. If your system supports this you should see several examples in there. (Note the username included in the line, in the same syntax as the old /etc/crontab)

这当然只适用于 root。如果您的系统支持此功能,您应该会在其中看到几个示例。(注意行中包含的用户名,语法与旧的 /etc/crontab 相同)

It's a sad misfeature in cron that there is no way to handle this as a regular user, and that so many cron implementations have no way at all to handle this.

cron 中的一个可悲的错误特征是没有办法作为普通用户来处理这个问题,而且很多 cron 实现根本没有办法处理这个问题。