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

crontab是否有不使用编辑器创建cron作业的参数(crontab -e)?如果是,从Bash脚本创建cron作业的代码是什么?

411980 次浏览

您可以向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行解释

* * * * * "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)

nixCraft来源。

编辑(固定覆盖):

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

不,crontab中没有修改cron文件的选项。

您必须:获取当前的cron文件(crontab -l > newfile),更改它并将新文件放置到位(crontab newfile)。

如果你熟悉perl,你可以使用这个模块配置:定时任务

LLP安德里亚

你可以在飞行中完成

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

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

如果你正在使用Vixie Cron,例如在大多数Linux发行版中,你可以把一个文件放在/etc/cron.D与个人cronjob。

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

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

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

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

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

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

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

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

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

另一个SO问题中找到这些。

谢谢大家的帮助。把我在这里和其他地方的发现拼凑起来,我得出了这个结论:

的代码

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

我想不出如何在不重复自己的情况下消除对这两个变量的需求。

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

细节

  1. 多亏了duckyflip,我使用这个小的重定向东西(<(*command*))将crontab -l的输出转换为fgrep命令的输入。
  2. fgrep然后过滤掉任何匹配的$command (-v选项),不区分大小写(-i选项)。
  3. 同样,小的重定向东西(<(*command*))用于将结果转回cat命令的输入。
  4. cat命令同样通过重定向(<(*command*))接收echo "$job"(不言自明)。
  5. 因此,crontab -l的过滤输出和简单的echo "$job"结合在一起,通过管道('|')传输到crontab -,最后写入。
  6. 他们从此过上了幸福的生活!

简而言之:

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

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

假设你有这些:

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

将它添加到crontab,不重复:

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

将它从crontab中删除,不管它当前的日程安排是什么:

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

注:

  • grep -F逐字匹配字符串,因为我们不想将其解释为正则表达式
  • 我们也忽略了时间调度,只寻找命令。这种方式;可以在没有向crontab添加新行风险的情况下更改时间表

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

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

一个只在没有找到所需字符串时才编辑crontab的变体:

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

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

使用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

在上面的例子中,我们在/etc/cron.d/中创建了一个文件,为命令的成功执行提供了环境变量,并为命令提供了usercommand本身。该文件不应该是可执行的,名称应该只包含字母-数字和连字符(详细信息如下)。

为了给出一个彻底的答案,让我们看看crontabcron/crond之间的区别:

crontab -- maintain tables for driving cron for individual users

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

cron -- daemon to execute scheduled commands

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

从手册中摘录了一些例子,告诉你应该做什么,不应该做什么:

/etc/crontab和/etc/crontab下的文件D必须由root拥有,并且不能是group或其他可写的。与线轴区域相反,在/etc/cron. .目录下的文件D或/etc/cron.目录下的文件每小时,/etc/cron.日报》/etc/cron.每周和/etc/cron.Monthly也可以是符号链接,只要符号链接和它所指向的文件都属于root用户。/etc/cron.目录下的文件D不需要可执行,而/etc/cron. .下的文件每小时,/etc/cron.日报》/etc/cron.每周和/etc/cron.因为它们是由run-parts运行的(有关更多信息,请参阅run-parts(8))。

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

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

下面是一个bash函数,用于向crontab添加命令而不重复

function addtocrontab () {
local frequency=$1
local command=$2
local job="$frequency $command"
cat <(fgrep -i -v "$command" <(crontab -l)) <(echo "$job") | crontab -
}
addtocrontab "0 0 1 * *" "echo hello"

脚本函数添加cronjob。检查重复条目,可用表达式* > "

cronjob_creator () {
# usage: cronjob_creator '<interval>' '<command>'


if [[ -z $1 ]] ;then
printf " no interval specified\n"
elif [[ -z $2 ]] ;then
printf " no command specified\n"
else
CRONIN="/tmp/cti_tmp"
crontab -l | grep -vw "$1 $2" > "$CRONIN"
echo "$1 $2" >> $CRONIN
crontab "$CRONIN"
rm $CRONIN
fi
}

测试:

$ ./cronjob_creator.sh '*/10 * * * *' 'echo "this is a test" > export_file'
$ crontab  -l
$ */10 * * * * echo "this is a test" > export_file

来源:我的大脑;)

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

给grep exact命令添加-w参数,不带-w参数添加cronjob "testing"会导致删除cronjob "testing123"

脚本函数添加/删除cronjob。无重复条目:

cronjob_editor () {
# usage: cronjob_editor '<interval>' '<command>' <add|remove>


if [[ -z "$1" ]] ;then printf " no interval specified\n" ;fi
if [[ -z "$2" ]] ;then printf " no command specified\n" ;fi
if [[ -z "$3" ]] ;then printf " no action specified\n" ;fi


if [[ "$3" == add ]] ;then
# add cronjob, no duplication:
( crontab -l | grep -v -F -w "$2" ; echo "$1 $2" ) | crontab -
elif [[ "$3" == remove ]] ;then
# remove cronjob:
( crontab -l | grep -v -F -w "$2" ) | crontab -
fi
}
cronjob_editor "$1" "$2" "$3"

测试:

$ ./cronjob_editor.sh '*/10 * * * *' 'echo "this is a test" > export_file' add
$ crontab  -l
$ */10 * * * * echo "this is a test" > export_file

我喜欢的解决方案是这样的:

(crontab -l | grep . ; echo -e "0 4 * * * myscript\n") | crontab -

这将确保您正确地处理底部的空白新行。为了避免crontab的问题,通常应该在crontab文件结束时添加一个空白的新行。上面的脚本确保它首先删除带有“grep .”部分的所有空行,然后在脚本末尾添加带有“\n”的新空行。如果现有crontab文件以空行结束,这还将防止在新命令上方出现空行。

所以,在Debian、Ubuntu和许多类似的基于Debian的发行版中……

有一个cron任务连接机制,它接受一个配置文件,将它们捆绑起来,并将它们添加到运行中的cron服务中。

你可以把一个文件放在/etc/cron.目录下D /somefilename,其中somefilename是你想要的任何东西。

sudo echo "0,15,30,45 * * * * ntpdate -u time.nist.gov" >> /etc/cron.d/vmclocksync

让我们来分解一下:

Sudo -因为您需要提升权限来更改/etc目录下的cron配置

Echo -在STD输出时创建输出的工具。printf,猫……也会起作用

-在你的字符串开头使用双引号,你是专业的

0,15,30,45 * * * * -标准的cron运行调度,每15分钟运行一次

ntpdate -u time.nist.gov -我想要运行的实际命令

-因为我的第一个双引号需要一个伙伴来关闭正在输出的行

>> -双重定向追加而不是覆盖*

/etc/cron.d/vmclocksync - vmclocksync是我选择的文件名,它在/etc/cron.d/


如果我们使用>重定向,我们可以保证我们只有一个任务条目。但是,我们将冒着破坏现有文件中任何其他规则的风险。你可以自己决定,如果可能的破坏>是正确的,或可能的重复>>是适合你的。或者,您可以执行一些复杂或复杂的操作,检查文件名是否存在,其中是否有任何内容,以及是否添加了任何类型的副本——但是,我有事情要做,现在不能为您做这些。

Bash脚本,用于在没有交互式编辑器的情况下添加cron作业。 下面的代码帮助您使用linux文件添加cronjob

#!/bin/bash


cron_path=/var/spool/cron/crontabs/root


#cron job to run every 10 min.
echo "*/10 * * * * command to be executed" >> $cron_path


#cron job to run every 1 hour.
echo "0 */1 * * * command to be executed" >> $cron_path
echo "0 * * * * docker system prune --force >/dev/null 2>&1" | sudo tee /etc/cron.daily/dockerprune
(2>/dev/null crontab -l ; echo "0 3 * * * /usr/local/bin/certbot-auto renew") | crontab -
cat <(crontab -l 2>/dev/null) <(echo "0 3 * * * /usr/local/bin/certbot-auto renew") | crontab -

#输出当前crontab

crontab -l > mycron 2>/dev/null

#echo new cron到cron文件中

echo "0 3 * * * /usr/local/bin/certbot-auto renew" >> mycron

#安装新的cron文件

crontab mycron


rm mycron

假设您是以“ubuntu”用户登录的,但您想将一个作业添加到另一个用户的crontab,例如“john"”。您可以执行以下操作:

(sudo crontab -l -u john; echo "* * * * * command") | awk '!x[$0]++' | sudo crontab -u john -

此解决方案的大部分源代码:https://www.baeldung.com/linux/create-crontab-script

我有吨的问题试图添加一个工作另一个用户的crontab。它不断复制crontab,或者直接删除它们。经过一些测试,我相信这行代码将附加一个新的作业到指定用户的crontab,非破坏性的,包括不创建一个已经存在的作业。

我想找一个这样的例子,所以可能会有帮助:

COMMAND="/var/lib/postgresql/backup.sh"
CRON="0 0 * * *"
USER="postgres"
CRON_FILE="postgres-backup"
# At CRON times, the USER will run the COMMAND
echo "$CRON $USER $COMMAND" | sudo tee /etc/cron.d/$CRON_FILE
echo "Cron job created. Remove /etc/cron.d/$CRON_FILE to stop it."