bash - Checking for duplicate cron jobs -


we deploying code our application server environment, , part of process creating number of cron jobs on server. when code gets pushed, our deployment script creates required cron jobs without problem using following:

cron_file=$script_dir/cron.txt  if [[ ! -f "$cron_file" ]];         printf "cron template file missing!\n\n"         exit 1 fi while read line || [[ -n "$line" ]];         printf "\n> adding cron job \"$line\"\n"         crontab -l | { cat; echo "$line"; } | crontab - done < $cron_file 

the issue after initial deployment, additional deployments creating duplicate cron jobs.

any pointers on how detect if cron job exists?

when add cron job, include comment unique label. later can use unique label determine if cron job exists or not, , "uninstall" cron job.

i time. have reusable script this:

#!/bin/sh # # usage:  # 1. put script somewhere in project # 2. edit "$0".crontab file, should this,  #    without # in front of lines #0  *   *   *   *   stuff_you_want_to_do #15 */5 *   *   *   stuff_you_want_to_do #*  *   1,2 *   *   and_so_on # 3. install crontab, run script # 4. remove 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 executable if type crontab >/dev/null 2>/dev/null;     if test $mode = add;         if ! crontab_exists;             crontab -l > $crontab_bak             echo 'appending crontab:'             cat $crontab             crontab -l 2>/dev/null | { cat; echo; echo $cron_unique_label; cat $crontab; echo; } | crontab -         else             echo 'crontab entry exists, skipping ...'             echo         fi         echo "to remove added crontab entry, run: $0 --remove"         echo     elif test $mode = remove;         if crontab_exists;             echo removing crontab entry ...             crontab -l 2>/dev/null | sed -e "\?^$cron_unique_label\$?,/^\$/ d" | crontab -         else             echo crontab entry not exist, nothing do.         fi     fi fi 

save script crontab.sh in project directory, , create crontab.sh.crontab cron job definitions, example:

0 0 * * * echo hello world 0 0 * * * date 
  • to install cron jobs, run ./crontab.sh
  • the script safe run multiple times: detect if unique label exists , skip adding cron jobs again
  • to uninstall cron jobs, run ./crontab.sh --remove

i put on github too: https://github.com/janosgyerik/crontab-script

explanation of sed -e "\?^$cron_unique_label\$?,/^\$/ d":

  • in simplest form expression basically: sed -e '/start/,/end/ d'
  • it means: delete content between lines matching start pattern , end pattern, including lines containing patterns
  • the script quotes sed command double-quotes instead of single quotes, because needs expand value of $cron_unique_label shell variable
  • the start pattern \?^$cron_unique_label\$? uses pair of ? instead of / enclose pattern, because $cron_unique_label contains /, cause problems
  • the starting ? must escaped backslash, honest don't know why.
  • the ^ matches start of line , $ end of line, , $ must escaped, otherwise shell expand value of $? shell variable
  • the end pattern /^\$/ relatively simple, matches start of line followed end of line, in other words empty line, , again $ must escaped
  • the d @ end sed command, delete matched lines, removing content of crontab -l, can pipe crontab -

Comments