shell 编写文件和文件夹拷贝函数
在 shell 终端拷贝文件夹和文件,是很简单的事情,直接 cp -arf
就搞定了。但是在自动化 shell 脚本中,可能会出现种种原因而导致拷贝失败或拷贝不全的情况,出问题的时候也无法核对是否拷贝成功,这时候黑锅就来了……
若想不背锅或快速排查问题,在拷贝文件夹或文件后进行文件核对并输出结果,就显得尤其重要。
首先,编写一个函数脚本( REPLACE_FILES.sh
):
#!/usr/bin/env bash
set -e
#替换文件夹内容
REPLACE_DIR(){
#获取源文件夹和目标文件夹
local DIR1=${1}
local DIR2=${2}
#创建目标文件夹
mkdir -p ${DIR2}
#拷贝源文件夹的文件到目标文件夹
set -x
cp -arf ${DIR1}/* ${DIR2}
set +x
#进行文件对比验证
#统计源文件夹文件名及md5信息并赋值
cd ${DIR1}
DIR1_MD5S=find . -type f -exec md5sum {} \;
DIR1_FILES=find . -type f
#获取文件夹名
DIR_NAME=basename ${DIR2}
#轮询比对
#当存在源目录的文件
for X in ${DIR1_FILES}
do
#获取文件MD5
DIR1_MD5=echo "${DIR1_MD5S}"|grep "${X}"|grep -v "${X}."|awk '{print $1}'
#获取目标目录对应文件的MD5
cd ${DIR2}
DIR2_MD5=find . -type f -wholename "${X}" -exec md5sum {} \;|awk '{print $1}'
#MD5比对
if [[ ${DIR1_MD5} == ${DIR2_MD5} ]]; then
echo -e "\n${DIR1_MD5}\n${DIR2_MD5}\n"
echo -e "\nREPLACE ${X} COMPLETE!\n"
else
echo -e "\n${DIR1_MD5}\n${DIR2_MD5}\n"
echo -e "\nREPLACE ${X} FAIL!\n"
exit 1
fi
done
echo -e "\nDIR ${DIR_NAME} REPLACE COMPLETE!\n"
}
#替换文件
REPLACE_FILE(){
#定义源文件和目标文件
local FILE1=${1}
local FILE2=${2}
#拷贝并替换文件
set -x
cp -af ${FILE1} ${FILE2}
set +x
#或者双方MD5值并进行比对
FILE1_MD5=md5sum ${FILE1}|awk '{print $1}'
FILE2_MD5=md5sum ${FILE2}|awk '{print $1}'
FILE_NAME=echo "${FILE2}"|awk -F "/" '{print $NF}'
if [[ ${FILE1_MD5} == ${FILE2_MD5} ]]; then
echo -e "\n${FILE1_MD5}\n${FILE2_MD5}\n"
echo -e "\n${FILE_NAME} REPLACE COMPLETE!\n"
else
echo -e "\n${FILE1_MD5}\n${FILE2_MD5}\n"
echo -e "\n${FILE_NAME} REPLACE FAIL!\n"
return 1
fi
}
然后调用此脚本内的函数,就能实现 MD5 比对并输出了:
#!/usr/bin/env bash
set -e;
cd dirname $0
#所有变量均在ENV.sh定义
. ./ENV.sh
. ./REPLACE_FILES.sh
DO_REPLACE_DIR(){
#支持多个文件夹循环替换,变量命名为(RELEASE_DIR,RELEASE_DIR2,RELEASE_DIR3...)(SRC_DIR,SRC_DIR2,SRC_DIR3...)
FCT=cat ../env/${ENV}.sh|grep "readonly RELEASE_DIR"|wc -l
for (( i = 1; i <= ${FCT}; i++ )); do
RELEASE_DIR1=${RELEASE_DIR}
SRC_DIR1=${SRC_DIR}
eval DIR1=\${RELEASE_DIR${i}}
eval DIR2=\${SRC_DIR${i}}
REPLACE_DIR ${DIR1} ${DIR2}
done
}
DO_REPLACE_FILE(){
#支持多个文件循环替换,变量命名为(RELEASE_FILE,RELEASE_FILE2,RELEASE_FILE3...)(SRC_FILE,SRC_FILE2,SRC_FILE3...)
FCT=cat ../env/${ENV}.sh|grep "readonly RELEASE_FILE"|wc -l
for (( i = 1; i <= ${FCT}; i++ )); do
RELEASE_FILE1=${RELEASE_FILE}
SRC_FILE1=${SRC_FILE}
eval FILE1=\${RELEASE_FILE${i}}
eval FILE2=\${SRC_FILE${i}}
REPLACE_FILE ${FILE1} ${FILE2}
done
}
DO_REPLACE_DIR
DO_REPLACE_FILE