如何以编程方式创建新的cron作业?

时间:2009-03-04 14:34:08

标签: linux unix cron

我希望能够以编程方式添加新的cron作业,最好的方法是什么?

my research开始,似乎我可以转储当前的crontab然后添加一个新的crontab,将其重新导入crontab:

(crontab -l ; echo "0 * * * * wget -O - -q http://www.example.com/cron.php") | crontab -

有更好的方法吗?

19 个答案:

答案 0 :(得分:113)

如果以root身份运行,最好的方法是将文件放入/etc/cron.d

如果您使用软件包管理器打包软件,您可以简单地在该目录中放置文件,它们被解释为它们是crontabs,但是有一个额外的用户名字段,例如:

文件名:/etc/cron.d/per_minute

内容: * * * * * root /bin/sh /home/root/script.sh

答案 1 :(得分:85)

OP的解决方案有一个错误,它可能允许添加两次条目,使用下面的方法进行修复。

(crontab -l ; echo "0 * * * * your_command") | sort - | uniq - | crontab -

答案 2 :(得分:21)

向cron添加内容

(crontab -l ; echo "0 * * * * hupChannel.sh") 2>&1 | grep -v "no crontab" | sort | uniq | crontab -

从cron中删除此内容

(crontab -l ; echo "0 * * * * hupChannel.sh") 2>&1 | grep -v "no crontab" | grep -v hupChannel.sh |  sort | uniq | crontab -

希望能帮到某人

答案 3 :(得分:6)

如果你计划为一次运行一次只做wget的事情,请看看'at'

答案 4 :(得分:5)

只需将编辑器更改为tee命令:

export EDITOR="tee"
echo "0 * * * * /bin/echo 'Hello World'" | crontab -e

答案 5 :(得分:4)

假设您的crontab中已有条目,则以下命令应该相对较好。请注意,$CMD变量仅用于提高可读性。在过滤重复项之前进行排序很重要,因为uniq仅适用于相邻的行。

CMD='wget -O - -q http://www.example.com/cron.php"'
(crontab -l ; echo "0 * * * * $CMD") | sort | uniq | crontab -

如果您当前有一个空的crontab,您将收到以下错误给stderr:

no crontab for user

如果你想避免这种情况,你可以添加一些复杂性添加做这样的事情:

(crontab -l ; echo "0 * * * * $CMD") 2>&1 | sed "s/no crontab for $(whoami)//"  | sort | uniq | crontab -

答案 6 :(得分:2)

man crontab也很有用:

CRONTAB(1)

NAME

   crontab - manipulate per-user crontabs (Dillon's Cron)

概要

   crontab file [-u user] - replace crontab from file

   crontab - [-u user] - replace crontab from stdin

   crontab -l [user] - list crontab for user

答案 7 :(得分:2)

添加到JohnZ的答案中,如果您是sudoer,这里是以root身份安排的语法:

(sudo crontab -l ; echo "0 * * * * your_command") | sort - | uniq - | sudo crontab -

答案 8 :(得分:1)

function cronjob_exists($command){

    $cronjob_exists=false;

    exec('crontab -l', $crontab);


    if(isset($crontab)&&is_array($crontab)){

        $crontab = array_flip($crontab);

        if(isset($crontab[$command])){

            $cronjob_exists=true;

        }

    }
    return $cronjob_exists;
}

function append_cronjob($command){

    if(is_string($command)&&!empty($command)&&cronjob_exists($command)===FALSE){

        //add job to crontab
        exec('echo -e "`crontab -l`\n'.$command.'" | crontab -', $output);


    }

    return $output;
}

    append_cronjob('* * * * * curl -s http://localhost/cron/test.php');

答案 9 :(得分:1)

这里的大多数解决方案都是为crontab添加行。如果您需要更多控制权,您将希望能够控制crontab的全部内容。

你可以使用滚边来做得非常优雅。

要完全重写crontab,请执行

echo "2 2 2 2 2 /bin/echo foobar" |crontab -

这应该很容易与这里描述的其他答案结合起来,如

crontab -l | <something> | tee |crontab -

或者,如果你有文件中的内容,它甚至更简单

cat <file> |crontab -

答案 10 :(得分:1)

这将检查以确保您的命令在添加之前不存在。

crontab -l 2>/dev/null | grep -q '/path/to/script' || echo "5 * * * * /path/to/script" | crontab -

干杯。

答案 11 :(得分:0)

将stdout导入crontab并没有在macOS上为我安装新的crontab,所以我找到了这个解决方案,使用子shell中的tee编辑器:

(EDITOR=tee && (crontab -l ; echo "@daily ~/my-script.sh" ) | uniq - | crontab -e)

答案 12 :(得分:0)

如果您希望任务以用户身份运行:

crontab -l | { cat; echo "@weekly what_you_want_to_execute"; } | crontab -

如果您希望任务以特权运行:

sudo crontab -l | { cat; echo "@weekly what_you_want_to_execute"; } | sudo crontab -

并检查任务(带有或不带有“ sudo”):

crontab -l | sed '/^$/d; /#/d'

答案 13 :(得分:0)

下面是我在脚本中使用的

1。

(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新的cron到cron文件中

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

#install新的cron文件

crontab mycron

rm mycron

答案 14 :(得分:0)

要在以后更改命令时具有灵活性,可以执行此操作(与更新脚本配合使用效果最好)

MARK=SOME_UNIQUE_MARK_TEXT
LINE="This is the command # $MARK"
# NOTE: I'm using -e because I might want to avoid weird bash expansions for '*' or '$' and place:
# \x2A instead of *
# \x24 instead of $
( crontab -l | grep -v $MARK ; echo -e "0 * * * *" $LINE ) | crontab -

通过这种方式,我可以更新旧的crontab命令,该命令不再用于当前目的。

基本上,我得到了当前的crontab,我删除了包含MARK(grep -v)的行,并通过echo -e将其添加到crontab文件的末尾,将其替换为新行。在这种特殊情况下,我希望它在每小时0 * * * *的第0分钟执行一次,就像从here可以看到的那样。

答案 15 :(得分:-1)

您也可以将任务添加到/ etc / cron。* /

答案 16 :(得分:-1)

这是另一种单线方式,可以避免重复

(crontab -l 2>/dev/null | fgrep -v "*/1 *  *  *  * your_command"; echo "*/1 *  *  *  * your_command") | crontab -

这是一种方法来做JohnZ的回答并避免no crontab for user消息,或者如果你需要在set -eu类型环境中操作而且不能有任何返回失败(在这种情况下{ {1}}部分是可选的):

2>/dev/null

或者如果你想分开一些东西以便它们更具可读性:

( (crontab -l 2>/dev/null || echo "")  ; echo "0 * * * * your_command") | sort -u - | crontab -

或者可选地删除对your_command的任何引用(例如:如果时间表已更改,您只希望它曾被一次cron'ed)。在这种情况下,我们不再需要new_job="0 * * * * your_command" preceding_cron_jobs=$(crontab -l || echo "") (echo "$preceding_cron_jobs" ; echo "$new_job") | sort - | uniq - | crontab - (额外奖励,插入顺序也会保留):

uniq

答案 17 :(得分:-2)

您也可以直接编辑cron表文本文件,但您的解决方案似乎完全可以接受。

答案 18 :(得分:-15)

它对我来说总是很好。

你应该考虑一个稍微复杂的脚本,可以做三件事。

  1. 附加crontab行;确保它不存在。在已经存在时添加是不好的。

  2. 删除crontab行。如果它不存在,也许只是警告。

  3. 上述两个功能的组合,用于替换crontab行。