增量发版脚本
[DateTime] 表示一个由时间日期信息生成的变量值,作为目录名称。
序号 |
脚本 |
说明 |
---|---|---|
1 |
zcw_mkdir4bak-2.2.sh | 创建目录 |
2 |
zcw_bak4release-3.2.sh | 备份目录 |
3 |
zcw_replace4release-2.0.sh | 替换文档 |
4 |
zcw_Virtualfile-2.0.sh |
处理新增文件 |
1 zcw_mkdir4bak-2.2.sh
用法,直接执行:
[root@right .donatello]# bin/zcw_mkdir4bak-2.2.sh Create directory, ok. >> /home/can_remove/20161229125912 Create directory, ok. >> /home/zcw_backup_op/20161229125912
创建目录是为了备份文件,创建的目录位于/home/zcw_backup_op/,/home/can_remove/下。
创建的目录名称完全由“日期时间”信息组成,例如:
[root@right .donatello]# cd /home/zcw_backup_op/ [root@right zcw_backup_op]# ll total 4 drwxr-xr-x. 3 root root 16 Dec 26 17:04 20161226100101 drwxr-xr-x. 3 root root 17 Dec 26 15:51 20161226135120 drwxr-xr-x. 3 root root 16 Dec 26 17:07 20161226170720
脚本内容(zcw_mkdir4bak-2.2.sh):
#!/bin/bash # Create backup & can_remove directory by donatello(15389222587). # ZCW_TS # Attached to the file "~/.bashrc" # added by donatelle, tel is 15389222587. # DATE=`which --skip-alias date` # export ZCW_TS=`$DATE +%Y%m%d%H` # # Reference: # ls -1 /home/zcw_backup_op/ | grep $ZCW_TS # # Commands LL="`which --skip-alias ls` -ld" L1="`which --skip-alias ls` -1" MKDIR="`which --skip-alias mkdir` -p" GREP="`which --skip-alias grep`" DATE="`which --skip-alias date`" # Variables REM="/home/can_remove/" BKD="/home/zcw_backup_op/" ZCW_TS="`$DATE +%Y%m%d%H`" ZCW_TS2="`$DATE +%M%S`" # Define function. # # Pre-run dependency checking. chkdir () { if [ ! -d $1 ]; then $MKDIR $1 &> /dev/null fi } chkrely () { # call f() above # chkenvariable chkdir $REM chkdir $BKD } # Create directory for backuping. # Will be called in other programs which judge the creation conditions. # mkzcwbakdir () { $MKDIR $1 &> /dev/null if [ ! $? -eq 0 ]; then echo -e "ERROR: There is error when create directory.\n>> $1" exit 1 fi echo -e "Create directory, ok.\n>> $1" } # Judge the creation condition, will call function "mkzcwbakdir ()". # Create directory per hour. # Position variables. # $1, The directory will be create. # $2, The directory contained date info(2016122016) which in current backup # directory. # mkifnotexist () { ${L1} ${1} | ${GREP} ${2} &> /dev/null if [ $? -eq 0 ]; then echo -en "Directory \"${1}${2}${ZCW_TS2}\" is exists.\t" echo "Only one folder can be created per hour." else mkzcwbakdir ${1}${2}${ZCW_TS2} fi } # Begin... # Check for dependencies chkrely # Fatal blow # Create several directories mkifnotexist ${REM} ${ZCW_TS} mkifnotexist ${BKD} ${ZCW_TS}
2 zcw_bak4release-3.2.sh
用法,需要一个参数,该参数必须是个存在的目录。如:
[root@right .donatello]# bin/zcw_bak4release-3.2.sh Usage: "bin/zcw_bak4release-3.2.sh /path/to/directory" The command must have a parameter that must be an existing, accessible directory at the run time. [root@right .donatello]# bin/zcw_bak4release-3.2.sh /data003/zhaocai Usage: "bin/zcw_bak4release-3.2.sh /path/to/directory" The command must have a parameter that must be an existing, accessible directory at the run time. [root@right .donatello]# bin/zcw_bak4release-3.2.sh /home/zhaocai/release/zhaocai/lib/ The current backup home directory: /home/zcw_backup_op/20161229130044/ Backup directory: home-zhaocai-release-zhaocai-lib Ok.
把指定的目录(作为参数传递给脚本)备份到”/home/zcw_backup_op/[DateTime]/“。备份支持多
次操作,不会覆盖上次备份的内容,而且位于相同备份目录下。目录合并,重复文件会以时间信息作为后缀
自动添加给文件名称。重复操作会占用双倍的磁盘空间。
有些需要重启后清理日志的操作,也可以用来备份日志。效果如下:
[root@iZ28lyaw0o0Z zcw_backup_op]# cd 20161229123917/ [root@iZ28lyaw0o0Z 20161229123917]# ll total 8 drwxr-xr-x 7 root root 4096 Dec 29 12:39 home-zhaocai-release-zhaocai drwxr-xr-x 2 root root 4096 Dec 29 12:41 home-zhaocai-tomcat-back-logs
备份后的文件夹名称是原文件路径名称加上文件名称。
脚本内容(zcw_bak4release-3.2.sh):
#!/bin/bash # The script is made by donatello. # This script relies on the script that generated the directory, # making sure that there is a valid directory after the call. # # Reference command # ls -t1 | head -1 # ls /home/zcw_backup_op/ -t1 | wc -l # # Variables # BKF Backup location. # HNAME The final backup directory under "/home/xxx/2016xxx00/". # SUFFIX Time stamp. BKF="/home/zcw_backup_op/" SUFFIX="`date +%H%M%S`" HNAME="" # Commands # LT1 The order of files in the directory is sorted by time. # Put the latest file in the first line. # HEAD Gets the string in the first line. LT1="`which --skip-alias ls` -t1" LSX="`which --skip-alias ls` -x" HEAD="`which --skip-alias head` -1" COPY="`which --skip-alias cp` -R -b --suffix=${SUFFIX}" BN="`which --skip-alias basename`" DN="`which --skip-alias dirname`" # Define functions printhelp () { echo "Usage: \"$0 /path/to/directory\"" echo "The command must have a parameter that must\ be an existing, accessible directory at the run time." } printBKFError () { echo "The path to the backup directory is incorrect." echo '$BKF='\""$BKF"\" } # Check various conditions. # Check backup directory. # The chkBKF will be called in achieve for judge. chkBKF () { if [ ! -d $BKF ]; then echo '-d' printBKFError exit 1 fi echo $BKF | grep "^/home/zcw_backup_op/20" &> /dev/null if [ ! $? == "0" ]; then echo '$? == "0"' printBKFError exit 1 fi } chkusage () { if [ ! $1 -eq 1 ]; then printhelp exit 1 fi } # Parameter verification of the command chkdestdir () { if [ ! -d $1 ]; then printhelp exit 1 fi } # Time more than one hour need to create another directory to store. # In order to determine whether need to create a folder for backuping. # Will be called in function "achieve" determineCreateDir () { local var1="`$BN $BKF`" local var2="$SUFFIX" # Debugging statement # echo $var1 # echo $var2 if [ ${var1:8:2} != ${var2:0:2} ]; then echo "You need to create a backup directory\ because the time interval is not in the same hours." exit 1 fi } # Determine the directory name and call function which create directory # named "determineCreateDir". achieve () { # Generate a backup directory. BKF="${BKF}`$LT1 $BKF | $HEAD`/" # Check that the path prefix is under "/home/zcw_backup_op/20". chkBKF $BKF # Create a folder every hour. determineCreateDir } # So that the generated backup directory can be understand easily. humanize () { local tmp_d="$1" local tmp_b="`$BN $tmp_d`" HNAME="${tmp_b}" # Internal function steamed_bread () { until [ "home" == "$tmp_b" ]; do tmp_d="`$DN $tmp_d`" tmp_b="`$BN $tmp_d`" HNAME="${tmp_b}-${HNAME}" # Debugging statement # echo "HNAME=$HNAME" done } steamed_bread } # Greet greet () { echo "The current backup home directory: $BKF" # Displays directory information local info="`${LSX} ${BKF}`" echo "Backup directory: $info" #echo "return $1" if [ $1 == "0" ]; then echo "Ok." else echo "Error in copy." fi } # Begin... # Check the correctness of the command. chkusage $# chkdestdir $1 # The variables "RMF" & "BKF" are reassigned by function "achieve". achieve # Fatal blow humanize $1 $COPY $1 ${BKF}${HNAME} greet $?
3 zcw_replace4release-2.0.sh
用法,执行运行。有个条件是,新文件(用来替换旧文件的文件)必须位于当前执行脚本的路径
下,目录结构不限制。可以直接处理中文在windows下编写的.txt说明文档。依照该说明文档的替换标准要求完成文件替换。
这个文档报错的可能性很大。说明文档被替换文件不存在(有可能是新增、有可能是路径错),当前目录下不存在新文件。
脚本内容(zcw_replace4RRelease-2.3.sh):
#!/bin/bash # zcw_replace4release-2.3.sh # Modify: # The documentation begins with a relative path, a relative path that # starts with a slash. ################################### # ----Variables. # README The document from develoers. Determine from function "chk_README". ### PROJECT: Add an absolute path. # ### TOL: The opening logo. # # NODOC Determine the number of file from develops. # Should be 1. # NOLDFILE The number of documents to be replaced. # FILE The old file that will be replaced now. # RMD Directory "/home/can_remove/" # README="" ### PROJECT & TOL: PROJECT="/home/work/release" TOL="/caiBao" declare -i NODOC="`find . -name "*.txt" | wc -l`" declare -i NOLDFILE="`find . -name "*.txt" -exec cat {} \; | grep "^${TOL}" | wc -l`" FILE="" RMD="/home/can_remove/" RMD="${RMD}`ls -1t $RMD | head -1`" SUFFIX="`date +%H%M%S`" # ----Command COPY="`which --skip-alias cp` -vR -b --suffix=${SUFFIX}" #MOVE="`which --skip-alias mv` -v -b --suffix=${SUFFIX}" MOVE="`which --skip-alias mv` -v -f" # ----Functions # Locate the legal documentation. chk_README () { if [ ! 1 -eq $NODOC ]; then echo "There are multiple document, invalid." clearOut fi if [ 0 -eq $NOLDFILE ]; then echo "The format of the document is incorrect, exit." clearOut fi README="`find . -name "*.txt"`" FILE="$(cat $README | grep "^${TOL}" | sed 's/[[:cntrl:]]$//')" # echo -e "function chk_README:\n$FILE" # exit 1 } # False alarm. f_alarm() { echo -en '\a' } # Exit 1 with error. clearOut () { f_alarm exit 1 } # for other program calling. # Will called by function: chk_fileExist, chk_fireArms. # Check if exit with 1. chkNum () { if [ 1 -eq $K ]; then echo "The Error occurred in $1." clearOut fi if [ 0 -eq $K ]; then #sleep 1 echo "$1 all ok." sleep 3 fi } # Check old files existence. # Check the existence of the relaced file. # chk_fileExist () { echo "Checking old files according to file $README." declare -i K=0 for i in $(echo $FILE) do i=${PROJECT}${i} if [ ! -f ${i} ]; then echo -e "+++ >>\t$i\n File^ invalid. Error" K=1 fi if [ -f $i ]; then #file $i #echo "File valid. Ok" echo -n "." fi done chkNum "Old files." } # Check for new file existence. # The file used to replace the old file. # chk_fireArms () { echo "Checking new files according to file $README." declare -i N=0 declare -i K=0 for i in $(echo $FILE) do i=${PROJECT}${i} i=`basename $i` #echo $i N=`find . -name "$i" | wc -l` if [ 1 -eq $N ]; then #echo "$i, Ok" echo -n "." else K=1 echo -e "\n$i invalid, Error\n" fi done chkNum "New files." } # Main function. # FN filename in document. # BN basename of file in document. # LN new file. # replace () { # FN File in $README. # BN Basename of File. # LN New file in current directory. local FN="" local BN="" local LN="" echo -n "Replacement begins within 3 seconds: " # echo -n ".";sleep 1;echo -n ".";sleep 1;echo ".";sleep 1 echo -ne "3\a\b"; sleep 1; echo -ne "2\a\b"; sleep 1; echo -ne "1\a\b"; sleep 1; echo -e "0\b" for i in $(echo ${FILE}) do i=${PROJECT}${i} FN="$i" BN=`basename $i` LN="`find . -name "$BN"`" # Debugging statement # echo "$BN" # echo -e "\t$FN" # echo -e "\t$LN" echo -e "\a"; sleep 0.25; echo -e "\a" ${COPY} ${FN} ${RMD} ${MOVE} ${LN} ${FN} done echo "all over, ok." } # Checking... # Determine the documentation and save in the README variable. chk_README # # Checking old files. chk_fileExist # # Checking new files. chk_fireArms # Fatal attack replace #over!
4.zcw_Virtualfile-2.0.sh
如果说明文档中某些文件是新增的,就先虚拟一个同名文件,然后继续替换。脚本的执行也需要借助说明文件。因为要是到了用到这个脚本,说明之前运行的脚本已经检查过说明文档了。这里不再检查。
#!/bin/bash # Virtualfile-2.0.sh # Virtual some file according to the documentation named "*.txt". # Command for Variables. FIND="`which --skip-alias find`" # Variables. # README Documentation. # TOL The start flag of file name. # tmp Save the name of the file that does not exist. # FN The file name in README. # DN The 'dirname' of file name in README. # BN The 'basename' of file name in README. README="`$FIND . -name "*.txt"`" TOL="^/home/" tmp="" FN="" DN="" BN="" # Commands. MKFILE="`which --skip-alias touch`" MKDIR="`which --skip-alias mkdir` -vp" DIRNAME="`which --skip-alias dirname`" BASENAME="`which --skip-alias basename`" #echo $MKFILE #echo $MKDIR #echo $DIRNAME #echo $BASENAME #exit 1 # Function check. # Check the file. chk_fileExist () { echo "chk_fileExist" for i in $(cat $README | grep "$TOL" | sed 's/[[:cntrl:]]$//'); do if [ ! -f $i ]; then echo "File <<<$i>>> is not exists." tmp="$i\n$tmp" else echo "File <<<$i>>> is exists." fi done } # Check the return value of the previous command. chk_result () { if [ $1 == "0" ]; then echo "ok" else echo "error" exit 1 fi } # Create a file that does not exist. cre_file () { echo "cre_file" for i in $(echo -e $tmp | grep -v "^$"); do echo $i DN="$($DIRNAME $i)" FN=$i if [ ! -d "$DN" ]; then echo -n "Create directory <<<$DN>>>, " $MKDIR $DN &> /dev/null chk_result $? fi echo $FN echo -n "Create file <<<${FN}>>>, " $MKFILE ${FN} &> /dev/null chk_result $? done } # Fatal blow. chk_fileExist #echo -e "Variable:\n$tmp" #echo "hello." cre_file
bash
检查脚本语法、调试执行脚本
$ bash -n adduser.sh $ bash -x adduser.sh