crontabを更新するためのスクリプト

はじめに

毎回crontabを手作業で更新するのが面倒くさい。
crontabの設定自体はGitで管理しているので、ファイルをcrontabコマンドに流して更新する形でスクリプト化する素案を考えてみた。

Source

update_crontab.sh

#!/usr/bin/env bash

crontab -l > /dev/null 2>&1
if [ $? -eq 0 ]; then
  declare backup_folder="${HOME}/work/`date +%Y-%m-%d`/backup"
  declare backup_file_name='crontab.bk'
  declare backup_file_path="${backup_folder}"/"${backup_file_name}"

  mkdir -p "${backup_folder}"
  if [ ! -d "${backup_folder}" ]; then
    echo -e 'Failed to make backup folder.'
    exit 1
  fi

  crontab -l > "${backup_file_path}"
  if [ ! -f "${backup_file_path}" ] || [ ! -s "${backup_file_path}" ]; then
    echo -e 'Failed to make crontab backup.'
    exit 1
  fi

  diff_result=$(diff <(crontab -l) <(cat "${backup_file_path}"))
  if [ $? -ne 0 ]; then
    echo -e "Created backup file is not correct. Please check it. [${backup_file_path}]"
    exit 1
  fi

  echo -e "Completed to create backup.[${backup_file_path}]"
  echo -e ""
fi

declare release_folder="${HOME}/work/`date +%Y-%m-%d`/release"
declare release_file_name='crontab'
declare release_file_path="${release_folder}"/"${release_file_name}"

mkdir -p "${release_folder}"
if [ ! -d "${release_folder}" ]; then
  echo -e 'Failed to make release folder.'
  exit 1
fi

echo -e '* * * * * :' > "${release_file_path}" # TODO Need to update this part because this is tmp logic now.
if [ ! -f "${release_file_path}" ] || [ ! -s "${release_file_path}" ]; then
  echo -e "Failed to prepare for release file. Please check target folder. [${release_folder}]"
  exit 1
fi

diff_result=$(diff <(crontab -l) <(cat "${release_file_path}"))
if [ -z "${diff_result}" ]; then
  echo -e "Canceled release because current crontab and \"${release_file_path}\" is same. Please check it."
  exit 1
fi

echo -e "Please confirm diff. Do you update crontab? [y/n]"
echo -e "-----"
echo -e "${diff_result}"
echo -e "-----"
read input_string
case "$input_string" in
  [Yy]|[Yy][Ee][Ss])
    crontab "${release_file_path}"
    if [ $? -ne 0 ]; then
      echo -e "Failed \"crontab ${release_file_path}\""
      exit 1
    fi
    ;;
  [Nn]|[Nn][Oo])
    echo -e "Stop to update crontab."
    exit 0
    ;;
  *)
    echo "undefined"
    exit 1
    ;;
esac

diff_result=$(diff <(crontab -l) <(cat "${release_file_path}"))
if [ ! -z "${diff_result}" ]; then
  echo -e "Unexpected crontab is set. Please check new crontab by yourself."

  # TODO Will add rollback function

  exit 1
fi


echo -e "Completed to update crontab successfully."

exit 0

README

update_crontab

This script is for updating crontab from file.

language

bash

※ I share my environment.

$ bash --version
GNU bash, version 5.1.16(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

flow

  • Check current crontab. If crontab is empty go to release step.
    • "crontab" is set currently. -> Go to backup step.
    • "crontab" is empty. -> Skip backup step.
  • Make Backup.
    • Make backup folder.
    • Backup current crontab.
    • Check backup.Take diff between current "crontab" and backup
  • Update "crontab"
    • Make release folder.
    • Take diff between current "crontab" and release target.
    • Confirm diff by user.
      • y -> Update "crontab"
      • n -> Stop to update "crontab"

Tips

こうすればsudo suでswitchしたuserのcrontabも更新できる。

read -sp "Please input your password: " _password; echo -e
echo ${_password}  |  sudo -S -k su -c 'bash update_crontab.sh'