检查重复的cron作业

Pau*_*ega 4 bash cron crontab

我们正在为我们的应用程序服务器环境部署代码,并且该进程的一部分是在服务器上创建许多cron作业.当代码被推送时,我们的部署脚本使用以下内容创建所需的cron作业而不会出现问题:

CRON_FILE=$SCRIPT_DIR/cron.txt 
if [[ ! -f "$CRON_FILE" ]]; then
        printf "Cron template file missing!\n\n"
        exit 1
fi
while read LINE || [[ -n "$LINE" ]]; do
        printf "\n> Adding cron job \"$LINE\"\n"
        crontab -l | { cat; echo "$LINE"; } | crontab -
done < $CRON_FILE
Run Code Online (Sandbox Code Playgroud)

问题是在初始部署之后,其他部署正在创建重复的cron作业.

关于如何检测cron作业是否已存在的任何指针?

Sto*_*ica 6

添加cron作业时,请添加带有唯一标签的注释.稍后您可以使用该唯一标签来确定是否存在cron作业,还可以"卸载"cron作业.

我一直这样做.我有一个可重用的脚本:

#!/bin/sh
#
# Usage: 
# 1. Put this script somewhere in your project
# 2. Edit "$0".crontab file, it should look like this, 
#    but without the # in front of the lines
#0  *   *   *   *   stuff_you_want_to_do
#15 */5 *   *   *   stuff_you_want_to_do
#*  *   1,2 *   *   and_so_on
# 3. To install the crontab, simply run the script
# 4. To remove the crontab, run ./crontab.sh --remove
# 

cd $(dirname "$0")

test "$1" = --remove && mode=remove || mode=add

cron_unique_label="# $PWD"

crontab="$0".crontab
crontab_bak=$crontab.bak
test -f $crontab || cp $crontab.sample $crontab

crontab_exists() {
    crontab -l 2>/dev/null | grep -x "$cron_unique_label" >/dev/null 2>/dev/null
}

# if crontab is executable
if type crontab >/dev/null 2>/dev/null; then
    if test $mode = add; then
        if ! crontab_exists; then
            crontab -l > $crontab_bak
            echo 'Appending to crontab:'
            cat $crontab
            crontab -l 2>/dev/null | { cat; echo; echo $cron_unique_label; cat $crontab; echo; } | crontab -
        else
            echo 'Crontab entry already exists, skipping ...'
            echo
        fi
        echo "To remove previously added crontab entry, run: $0 --remove"
        echo
    elif test $mode = remove; then
        if crontab_exists; then
            echo Removing crontab entry ...
            crontab -l 2>/dev/null | sed -e "\?^$cron_unique_label\$?,/^\$/ d" | crontab -
        else
            echo Crontab entry does not exist, nothing to do.
        fi
    fi
fi
Run Code Online (Sandbox Code Playgroud)

将脚本保存crontab.sh在项目目录中,并crontab.sh.crontab使用您的cron作业定义创建一个,例如:

0 0 * * * echo hello world
0 0 * * * date
Run Code Online (Sandbox Code Playgroud)
  • 要安装您的cron作业,只需运行即可 ./crontab.sh
  • 该脚本可以安全地运行多次:它将检测是否已存在唯一标签,并再次跳过添加cron作业
  • 要卸载cron作业,请运行 ./crontab.sh --remove

我也把它放在GitHub上:https://github.com/janosgyerik/crontab-script

说明sed -e "\?^$cron_unique_label\$?,/^\$/ d":

  • 最简单的表达方式基本上是: sed -e '/start/,/end/ d'
  • 这意味着:删除与开始模式和结束模式匹配的行之间的内容,包括包含模式的行
  • 该脚本sed使用双引号而不是单引号引用该命令,因为它需要扩展$cron_unique_labelshell变量的值
  • 启动模式\?^$cron_unique_label\$?使用一对?而不是/包含模式,因为$cron_unique_label包含/,这将导致问题
  • 首发?必须用反斜杠进行转义,但说实话我不知道为什么.
  • ^场比赛线路和启动$行的末尾,而$必须转义,否则外壳将扩大的价值$?shell变量
  • 结束模式/^\$/相对简单,它匹配行的开头,后跟行尾,换句话说是空行,并且$必须再次转义
  • 所述d在端部是sed命令,删除该匹配线,有效地从内容删除它crontab -l,我们可以通过管道到crontab -


Lig*_*mer 5

奇怪但非常彻底的答案。IMO 过于复杂。

对于所有前来寻求 2017 年答案的人来说,这里有一篇不错的文章:

crontab -l | grep 'match-your-cronjob-search' || (crontab -l 2>/dev/null; echo "* * * * * /bin/cronjobCommandYouWant >> /dev/null 2>&1") | crontab -
Run Code Online (Sandbox Code Playgroud)

对于我们来说,避免出现重复的 cron 非常有用。

这是原始海报的编辑脚本:

    CRON_FILE=$SCRIPT_DIR/cron.txt 
if [[ ! -f "$CRON_FILE" ]]; then
        printf "Cron template file missing!\n\n"
        exit 1
fi
while read LINE || [[ -n "$LINE" ]]; do
        printf "\n> Adding cron job \"$LINE\"\n"
        crontab -l | grep "$LINE" || (crontab -l 2>/dev/null; echo "$LINE") | crontab -
done < $CRON_FILE
Run Code Online (Sandbox Code Playgroud)