之前分享过两篇文章 Linux 下用shell脚本对SVN 修改的文件进行备份 和 window 或 linux 下,svn版本控制,打包修改的文件及恢复 ,简单地介绍用shell 脚本实现修改文件的备份和恢复。今天分享一个完整版本。
#!/bin/sh
#以当前时间作为目录名
DATE_DIR=`date "+%Y-%m-%d_%H_%M_%S"`
#备份文件包所在目录
BACKUP_PATH=/home/tianyexing/backup_modify_code
#备份目录绝对目录
BACKUP_DIR=${BACKUP_PATH}/${DATE_DIR}
# 首先创建备份目录
if [ ! -d ${BACKUP_DIR} ]; then
mkdir -p ${BACKUP_DIR}
fi
#脚本所在路径
bashpath=$(cd `dirname $0`; pwd)
echo "script file in direcotry: ${bashpath}"
#切到git工作目录下
cd /home/tianyexing/develop_code/npti.src/
#获取当前所在分支名称
branch_name=$(git branch | grep '^*' | awk '{print $2}')
total_modified_file=0
total_new_files=0
for files in $(git status | grep -e \.cpp$ -e \.cc$ -e \.c$ -e \.h$ -e "Makefile" -e \.mk$ -e \.lua$ -e \.txt -e "Custom" -e "vendors" -e \.a$ -e \.patch -e \.robot -e \.py -e \.xmsg | grep -v IncludeVersion | awk '$NF ~/.cpp|.c|.cc|.h|.mk|.lua|.txt|.a|Custom|.xmsg|vendors\
|.patch/ {print $NF}')
do
file_path=`dirname $files` #取文件路径
abso_path=${BACKUP_DIR}/${file_path} #逐层建目录
mkdir -p ${abso_path}
if [ -n ${files} -a -f ${files} ]; then
echo "${files}"
let total_modified_file++
cp ${files} ${abso_path} #拷贝文件到对应目录下
fi
done
#这里是检查是否有新增的文件
echo -e "\033[31m"
echo "begin detect the new cpp files!!!!!!!"
echo -e "\033[0m"
for files in $(git status | awk '{print $NF}')
do
if [ -d ${files} ] && ls ${files} | grep -q -e \.cpp$ -e \.h$ ; then
echo "${files}"
abso_path=${BACKUP_DIR}/${files} #逐层建目录
mkdir -p ${abso_path}
for cpp_file in $( find ${files} -name "*.cpp" -or -name "*.h")
do
cp ${cpp_file} ${abso_path}
let total_new_files++
done
fi
done
if [ ${total_modified_file} -eq 0 -a ${total_new_files} -eq 0 ]; then
echo "no file modified and no new file add, delete dir: [${BACKUP_DIR}] !!!"
rm -rf ${BACKUP_DIR}
echo $?
exit 1
fi
echo -e "\033[31m"
echo "total ${total_modified_file} files modified!!"
echo "total ${total_new_files} files add!!"
echo "input a log in English: \"quit\" to cancle(nothing to do) !!!!!!!!!!!"
echo -e "\033[0m"
#读取用户输入,超时5秒
read -p "input log message:" -t 5 TEXT
#先赋给一个临时变量再比较,若用${TEXT} 去比较的话会提示一个错误
log_text=${TEXT}
if [ "${log_text}" = "quit" ]; then
#删除文件夹,不作打包备份
echo "nothing to do..........."
cd ${BACKUP_PATH}
rm -rf ${DATE_DIR}
exit 1
elif [ -z ${log_text} ]; then #超时后默认给一个
TEXT="code backup, no input manually"
fi
#切到备份目录下
cd ${BACKUP_PATH}
#先写入一空行到文件再写日志
echo >> readme.txt
#打包压缩
ARCHIVE_NAME=${DATE_DIR}.tar.gz
tar -czf ${ARCHIVE_NAME} ./${DATE_DIR}
rm -rf ${DATE_DIR}
#把包名和日志写入文件
echo "${ARCHIVE_NAME} --------- ${TEXT} [in branch ${branch_name}]" >> readme.txt
脚本里添加了 read 的超时输入,是想着定时执行这个脚本的,如果定时执行就没有手动输入这个动作,所以添加超时,超时后给一个默认日志写到 readme.txt,下图就是用 crontab 添加周期执行工作后的结果:
恢复文件的脚本:
#!/bin/sh
if [ $# -ne 1 ]; then
echo "Usage: $0 dir(date directory, if no one please decompress first)"
exit 1
fi
SRC_DIR=/home/tianyexing/develop_code/npti.src/
for files in $(find ./$1 -name "*.cpp" -or -name "*.c" -or -name "*.cc" -or -name "*.h" -or -name "*.sh" -or -name "*.mk")
do
path=`dirname ${files}` #获取相对路径
file_name=`basename ${files}` # 得到文件名
path_tmp=${path#*/} #去掉./
path_tmp=${path_tmp#*/} #去掉日期目录
abs_path=${SRC_DIR}${path_tmp} #获取绝对路径
echo "cp ${files} ${abs_path}" # 拷贝文件到目标路径
cp ${files} ${abs_path}
done
for 语句根据备份的文件类型添加相应的文件后缀即可。这个脚本要放在和压缩包同级目录下执行,第一步先解压包,第二步执行脚本:./recoverCPP.sh 2023-04-28_16_40_01