近段时间需要做一些网站程序更新的工作,每次的操作都是先将本地最新的程序打包然后 rz 上传至服务器,再解压出来,然后再找出那些不能覆盖的程序(例如配置文件)删除掉,接着是备份好先前的程序,再将最新的覆盖过去,最后还要改好所属用户组等等,一系列的操作虽然不是什么难事,但步骤比较多,很容易就会出现差错,而且每次做这些重复性的工作,总感觉有点浪费时间,倒不是省事点,直接传一个包上来就直接一次处理完,不需要操心,所以我想着写了一个简单的shell脚本去处理这些事,就当是练习下。
#!/bin/bash
if [ $# -lt 1 ]; then
zip_name='source'
else
zip_name=$1
fi
bak_num=5
set_path='/data/'
zip_path=$set_path$zip_name'.zip'
cp_from=$set_path$zip_name
cp_to=$set_path'bak'
if [ ! -f $zip_path ]; then
echo $zip_path'----不存在'
exit
fi
###########可以备份也可以不备份#################
if [ "$2x" != 'nobackupx' ]; then
echo '备份数据...'
cp -R $cp_to $cp_to'_'$(date +%Y%m%d)
fi
###########################
echo '解压数据源...'
unzip -o $zip_path -d $set_path
#########清除不更新的程序#############
echo '清理不更新数据...'
del_array=(
'/favicon.ico'
'/config
'/log'
'/a'
'/d'
)
for i in ${del_array[@]}
do
echo $i
rm -rf $cp_from$i
done
######################################
echo '更改用户组'
chown -R www:root $cp_from
#####################
echo '复制数据....'
\cp -a -r $cp_from/* $cp_to
#############清除数据##################
echo '清除复制源'
rm -rf $zip_path $cp_from
#########删除多余的备份#############
echo '删除旧备份数据开始......'
had_bak_count=`find $set_path -maxdepth 1 -type d -name "bak_*"|grep -P 'bak_[0-9]{8}'|wc -l`
if [ $bak_num -lt $had_bak_count ]; then
rm_count=`expr $had_bak_count - $bak_num`
echo `find $set_path -maxdepth 1 -type d -name "bak_*"|grep -P 'bak_[0-9]{8}'|sort|head -$rm_count`
find $set_path -maxdepth 1 -type d -name "bak_*"|grep -P 'bak_[0-9]{8}'|sort|head -$rm_count|xargs rm -rf
fi
echo 'complete'
在上面的脚本执行过程中,有一步数据备份,脚本里面直接使用的是cp 命令,这是完整的目录备份,若项目备份过程中有必要排除一些不需要备份的目录或者文件,此时cp就显得力不从心了,此时可以将cp操作改成rsync来处理。
首先要判断服务器是否安装了rsync,直接输入rsync命令回车即可,若有帮助信息出现证明已经安装过了,若没有可以直接:yum install rsync
此时只需要将cp操作改成:
rsync -av --exclude 'data/upload' $cp_to/* $cp_to'_'$(date +%Y%m%d)
此处需要注意的是,--exclude 对应的目录或者文件是相对于复制目录的,也就是复制目录下的相对目录路径,如上面的$cp_to/* 是将$cp_to目录下面的所有文件或者目录复制,此时--exclude 中的 data/upload 就指的是 $cp_to目录下面的data/uplaod,也就是 $cp_to/data/upload。
若--exclude的文件或者文件夹有多个,可直接使用 --exclude 'abc' --exclude 'bcd' 这种方式或者创建一个exclude.list文件,将路径写入里面,使用 --exclude-from=/exclude.list 参数引入文件的方式来排除。记得记录在exclude.list文件里面的路径也是相对路径。