使用shell程序备份crontab中的.sh脚本文件

时间:2022-09-23 11:03:13

需求

线上环境有一些定时脚本(用crontab -l可查看当前用户的),有时我们可能会改这些定时任务的脚本内容。为避免改错无后悔药,需用shell实现一个程序,定时备份crontab中的.sh脚本文件

分析与思考

所有用户的crontab放在/var/spool/cron/目录,各个用户放在各自目录下。只要把这些用户的crontab读取出来,提取出其中的.sh文件,然后按照用户备份到相应目录就行。最后配一个crontab,定时去执行这个备份程序。

备份程序的实现

#!/bin/bash
# this shell script from  https://www.cnblogs.com/itwild/

# backup dir
# root user will in ${bak_dir}/root, itwild user will in ${bak_dir}/itwild
bak_dir=/var/itwild

# new file will end with 2020-02-24_00:28:56
bak_suffix=$(date '+%Y-%m-%d_%H:%M:%S')

if [[ ! $bak_dir == */ ]]; then
    bak_dir="${bak_dir}/"
fi

create_dir_if_not_exist() {
    u="$1"
    user_bak_dir="${bak_dir}$u"

    if [ ! -d "$user_bak_dir" ]; then
        mkdir -p $user_bak_dir
        chown -R ${u}:${u} $user_bak_dir
    fi
}

backup_files() {
    u="$1"
    files=$2

    for f in ${files[*]}; do
        if [[ $f == *.sh ]]; then
            # only backup file which end with .sh
            copy_file $u $f
        fi
    done
}

copy_file() {
    u="$1"
    filepath=$2

    if [ ! -f "$filepath" ];then
        return
    fi

    user_bak_dir="${bak_dir}$u"
    filename=${filepath##*/}
    cur_ms=$[$(date +%s%N)/1000000]
    # avoid same filename here add cur_ms to distinct
    newfilepath="${user_bak_dir}/${filename}.${bak_suffix}.${cur_ms}"

    # switch to user and then copy file to right position
    su - $u -c "cp $filepath $newfilepath"
}

# start from here
cd /var/spool/cron/

for u in `ls`
do
    create_dir_if_not_exist $u
    files=$(cat $u | awk '{for(i=6;i<=NF;++i) printf $i" "}')
    backup_files $u "${files[*]}"
done

说明

  • 此脚本需要用root用户去执行,因为它会把所有用户的crontab都备份到相应目录
  • 然后把这个程序配成crontab就能完成定时备份的任务
  • 此程序仅仅自用,方便以后查询shell的一些用法