Chinaunix首页 | 论坛 | 博客
  • 博客访问: 328806
  • 博文数量: 32
  • 博客积分: 822
  • 博客等级: 准尉
  • 技术积分: 388
  • 用 户 组: 普通用户
  • 注册时间: 2011-05-27 13:55
文章分类

全部博文(32)

文章存档

2019年(2)

2017年(4)

2016年(9)

2015年(1)

2014年(1)

2012年(2)

2011年(13)

我的朋友

分类: 系统运维

2016-03-03 10:36:12

运用场景:
      每当我们为很多安装同样的机器升级或者更新服务时,要备份配置文件中的某一行或者多行,或者一个数据块或者多个数据块,和服务升级、更新完后,再把对应的备份数据重新写回新的配置文件中;在大批量的服务器中操作,会浪费很多的时间和精力,以下脚本就是用来完成类似的事情。
主要功能有:
      1.备份指定的一行或者多行,一个块或者多个块
      2.备份指定的单个文件
      3.还原所有部分备份和所有备份
      4.配置文件精确定位插入【正则匹配】
      5.配置文件精确定位删除
      6.配置文件类似行后批量插入
       服务的配置文件样例:
点击(此处)折叠或打开
  1. server.config:
  2. ####配置文件样例:
  3. ser_max_connection=6000 #行
  4. ser_min_connection=10

  5. ser_time_out=60
  6. ser_time_spent=120

  7. server tcp_nodes{ ##块
  8.    
  9.    ser_client_ip=ipv4
  10.    ser_client_len=20*N
  11.    ser_client_syn=yes
  12.    ser_client_ack=yes
  13. }
以下是shell脚本的代码实现,脚本主要是利用sed工具来完成配置编辑功能。此脚本是根据真实应用环境中改成通用版本,并没有经过严格的测试,如果你想要用此脚本,还请根据自己的环境下,做严重的测试。如果你有更好的想法,请加入QQ群:63565867

点击(此处)折叠或打开

  1. #!/bin/bash
  2. #DianDian
  3. proconf=/usr/local/server/etc #要备份的主目录,参数传入的文件名和会这个路径合并起来
  4. confpath=$proconf
  5. bkpath=/usr/local/src/bkconfig/part #备份文件中部分内容的保存目录
  6. bkpath_whole=/usr/local/src/bkconfig/whole #备份整个文件的保存目录
  7. handle_date=$(date "+%y%m%d%H%M")
  8. mkdir -p $bkpath $bkpath_whole
  9. FJ='^\+'
  10. FD='^\='
  11. ALLFILE=""

  12. function multidir(){ #dirname ##shell里面的一个递归函数,用来获得一个目录下的所有文件【如果文件名中包括空格,可能会出错】

  13.         local dirs=$1
  14.         local diri=0
  15.         if [ ! -d $dirs ];then
  16.                 echo "$dirs is not a directory."
  17.                 exit 1
  18.         fi
  19.         local lsfile=$(ls -d $dirs/* 2>/dev/null)
  20.         local dir_list=($lsfile)
  21.         for((diri=0;diri<${#dir_list[@]};diri++)){
  22.             if [ -d ${dir_list[$diri]} ];then
  23.                 multidir ${dir_list[$diri]}
  24.             else
  25.                 ALLFILE="$ALLFILE ${dir_list[$diri]}"
  26.             fi
  27.         }
  28. }

  29. if [ "X$1" == "Xbackup" ];then
  30.     num=0
  31.     if [ "X$2" != "X" ];then
  32.         OLD_IFS="$IFS"
  33.         IFS="#"
  34.         field=($2)
  35.         IFS="$OLD_IFS"
  36.     else
  37.         echo -e "\033[31m Error \033[0m"
  38.         exit 1
  39.     fi
  40.     SFS="+"
  41.     F_CONF="$confpath/${field[0]}"
  42.     B_CONF="$bkpath/${field[0]}"
  43.     B_CDIR=$(dirname $B_CONF)
  44.     if [ -e "$B_CONF" -a -s "$B_CONF" ];then
  45.         echo -e "\033[31m Error $B_CONF exist and no empty. \033[0m"
  46.         exit 1
  47.     fi
  48.     if [ ! -d $B_CDIR ];then
  49.         mkdir -p $B_CDIR
  50.     fi
  51.     if [ -f "$F_CONF" ];then
  52.         echo "backup @${field[0]}"
  53.         while read line
  54.         do
  55.             ((num++))
  56.             for((i=1;i<${#field[@]};i++)){
  57.                 if [[ ${field[$i]} =~ $FJ ]];then
  58.                     ST=${field[$i]#+}
  59.                     if [[ $line =~ ^$ST ]];then
  60.                         sed -n "$num,/}/p" $F_CONF | sed '1s/^/&+/' >> $B_CONF
  61.                     fi
  62.                 elif [[ ${field[$i]} =~ $FD ]];then
  63.                     ST=${field[$i]#=}
  64.                     STLine=${line%%=*}
  65.                     if [[ "$STLine" == "$ST" ]];then
  66.                         sed -n "${num}p" $F_CONF | sed '1s/^/&=/' >> $B_CONF
  67.                     fi
  68.                 else
  69.                     if [[ $line =~ ^${field[$i]} ]];then
  70.                         sed -n "${num}p" $F_CONF | sed '1s/^/&-/' >> $B_CONF
  71.                     fi
  72.                 fi
  73.             }
  74.         done < $F_CONF
  75.     else
  76.         echo -e "\033[31m Error:Skip ${field[0]} \033[0m"
  77.     fi
  78. elif [ "X$1" == "Xrestore" ];then
  79.     if [ "X$2" != "X" ];then
  80.         List=(`ls -f $bkpath/$2 2>/dev/null`)
  81.     else
  82.         #List=(`ls -d $bkpath/* 2>/dev/null`)
  83.         multidir $bkpath
  84.         List=($ALLFILE)
  85.     fi
  86.     if [ "$List" == "" ];then
  87.         echo -e "\033[31m restore:no valid file. \033[0m"
  88.     fi
  89.     for i in ${List[*]}
  90.     do
  91.         num=0
  92.         B_CONF="$i"
  93.         base=$(basename $i)
  94.         if [ "$base" == "" -a -s $B_CONF ];then
  95.             echo -e "\033[31m restore error @ $B_CONF \033[0m"
  96.             continue
  97.         fi
  98.         F_CONF=$(echo $i | sed -n "s#$bkpath#$confpath#p")
  99.         #F_CONF="$confpath/$base"
  100.         echo -n "@ $F_CONF "
  101.         if [ ! -f $F_CONF ];then
  102.             echo -e "\033[31m restore error @ $F_CONF \033[0m"
  103.             continue
  104.         fi
  105.         while read bconf
  106.         do
  107.             ((num++))
  108.             TT=""
  109.             Str=""
  110.             if [[ $bconf =~ $FJ ]];then
  111.                 Str=$(sed -n -e "${num},/}/p" $B_CONF | sed '1s/^+//' | awk '{S=S"\\n"$0;}END{sub(/^../,"",S);printf("%s",S);}')
  112.                 TT="+"
  113.             elif [[ $bconf =~ $FD ]];then
  114.                 Str=$(sed -n -e "${num}p" $B_CONF | sed '1s/^=//' | awk '{S=S"\\n"$0;}END{sub(/^../,"",S);printf("%s",S);}')
  115.                 TT="="
  116.             elif [[ $bconf =~ ^- ]];then
  117.                 Str=$(sed -n -e "${num}p" $B_CONF | sed '1s/^-//' | awk '{S=S"\\n"$0;}END{sub(/^../,"",S);printf("%s",S);}')
  118.                 TT="-"
  119.             else
  120.                 continue
  121.             fi
  122.             First=$(echo -e $Str | sed -n 1p)
  123.             seek=0
  124.             while read fconf
  125.             do
  126.                 ((seek++))
  127.                 tmp_fconf=${fconf%%=*}
  128.                 tmp_first=${First%%=*}
  129.                 if [ "$tmp_fconf" == "$tmp_first" ];then
  130.                     if [ "$TT" == "+" ];then
  131.                         sed -i "${seek},/}/d" $F_CONF
  132.                         if [ $seek -ne 1 ];then
  133.                             sed -i "$[ ${seek} - 1 ]a$Str" $F_CONF
  134.                         else
  135.                             sed -i "${seek}a$Str" $F_CONF
  136.                         fi
  137.                         echo -n "$TT"
  138.                         TT=""
  139.                         break
  140.                     elif [ "$TT" == "=" ];then
  141.                         sed -i "${seek}s/.*/$Str/" $F_CONF
  142.                         echo -n "$TT"
  143.                         TT=""
  144.                         break
  145.                     elif [ "$TT" == "-" ];then
  146.                         sed -i "${seek}s/.*/$Str/" $F_CONF
  147.                         echo -n "$TT"
  148.                         TT=""
  149.                         break
  150.                     fi
  151.                 fi
  152.             done < $F_CONF
  153.             if [ "$TT" != "" ];then
  154.                 Err=$Err" $First\n"
  155.             fi
  156.         done < $B_CONF
  157.         echo
  158.     done
  159.     if [ "$Err" != "" ];then
  160.         echo -e "\n\033[33mError: $Err\033[0m"
  161.         Err=""
  162.     fi
  163. elif [ "X$1" == "Xinsert" ];then
  164.     num=0
  165.     snum=0
  166.     n=1
  167.     nn=0
  168.     OLD_IFS="$IFS"
  169.     IFS="#"
  170.     if [ "X$2" != "X" ];then
  171.         insert=($2)
  172.     else
  173.         echo -e "\033[31m Insert Error \033[0m"
  174.         exit 1
  175.     fi
  176.     IFS="$OLD_IFS"
  177.     if [ -f "$confpath/${insert[0]}" ];then
  178.         while read olc
  179.         do
  180.             ((num++))
  181.             tmp_olc=$(echo "$olc" | sed 's/ //g')
  182.             tmp_olc=${tmp_olc%%=*}
  183.             tmp_insert=$(echo "${insert[$n]}" | sed 's/ //g')
  184.             tmp_insert=${tmp_insert%%=*}
  185.             if [[ "$tmp_olc" == $tmp_insert && $n -le ${#insert[@]} ]];then
  186.                 ((n++))
  187.                 if [ $n -eq $[ ${#insert[@]} - 1 ] ];then
  188.                     echo "Insert: ${insert[$n]} @ ${insert[0]}[$num]"
  189.                     snum=$num
  190.                     nn=$n
  191.                 elif [ $n -eq ${#insert[@]} ];then
  192.                     echo -e "\033[33m${insert[$nn]} exits.\033[0m"
  193.                     exit 1
  194.                 fi
  195.             else
  196.                 if [[ $num -eq $[ $snum + 2 ] && $nn -eq $n ]];then
  197.                     break
  198.                 fi
  199.             fi
  200.         done < $confpath/${insert[0]}
  201.         if [ $nn -ne $[ ${#insert[@]} - 1 ] ];then
  202.             echo -e "\033[31m Insert Error: None ${insert[$nn]} \033[0m $[ $nn + 1 ]"
  203.             exit 1
  204.         fi
  205.         Str="${insert[$nn]}"
  206.         sed -i "${snum}a\\$Str" $confpath/${insert[0]}
  207.     else
  208.         echo -e "\033[31m Insert Error:File not exist $confpath/${insert[0]} \033[0m"
  209.     fi
  210. elif [ "X$1" == "Xdelete" ];then
  211.     num=0
  212.     n=1
  213.     del=0
  214.         OLD_IFS="$IFS"
  215.         IFS="#"
  216.         if [ "X$2" != "X" ];then
  217.             delete=($2)
  218.         else
  219.             echo -e "\033[31m Delete Error \033[0m"
  220.             exit 1
  221.         fi
  222.         IFS="$OLD_IFS"
  223.         if [ -f "$confpath/${delete[0]}" ];then
  224.             while read olc
  225.             do
  226.                 ((num++))
  227.                 tmp_olc=$(echo "$olc" | sed 's/ //g')
  228.                 tmp_olc=${tmp_olc%%=*}
  229.                 tmp_delete=$(echo "${delete[$n]}" | sed 's/ //g')
  230.                 tmp_delete=${tmp_delete%%=*}
  231.                 #echo "$tmp_olc"
  232.                 if [[ $tmp_olc == $tmp_delete ]];then
  233.                     ((n++))
  234.                     if [ $n -eq $[ ${#delete[@]} ] ];then
  235.                         echo "Delete: ${delete[$n-1]} @ ${delete[0]}[$num]"
  236.                         del=1
  237.                         break
  238.                     fi
  239.                 fi
  240.             done < $confpath/${delete[0]}
  241.             if [ $n -ne $[ ${#delete[@]} ] ];then
  242.                 echo -e "\033[33mCan't find:\"${delete[$n]}\"@ $[ $n + 1 ] \033[0m"
  243.                 exit 1
  244.             fi
  245.             sed -i "${num}d" $confpath/${delete[0]}
  246.         else
  247.             echo -e "\033[31m Delete Error:File not exist $confpath/${delete[0]} \033[0m"
  248.         fi
  249. elif [ "X$1" == "Xinsall" ];then
  250.     OLD_IFS="$IFS"
  251.     IFS="#"
  252.     if [ "X$2" != "X" ];then
  253.         insert=($2)
  254.     else
  255.         echo -e "\033[31m insall Error \033[0m"
  256.         exit 1
  257.     fi
  258.     IFS="$OLD_IFS"
  259.     if [ -f "$confpath/${insert[0]}" ];then
  260.         sed -i "/${insert[1]}/a\\${insert[2]}" $confpath/${insert[0]}
  261.     fi
  262. elif [ "X$1" == "Xcopy" ];then
  263.     if [ "X$2" != "X" ];then
  264.         OLD_IFS="$IFS"
  265.         IFS="#"
  266.         field=($2)
  267.         IFS="$OLD_IFS"
  268.     else
  269.         echo -e "\033[31m Copy Error \033[0m"
  270.         exit 1
  271.     fi
  272.     for((i=0;i<${#field[@]};i++)){
  273.         Deep=$(dirname ${field[$i]} 2>/dev/null)
  274.         copied_dir=$confpath/$Deep
  275.         copied_file=$confpath/${field[$i]}
  276.         bk_dir=$bkpath_whole/$Deep
  277.         bk_file=$bkpath_whole/${field[$i]}
  278.         if [ ! -d "$copied_dir" -o ! -f "$copied_file" ];then
  279.             echo -e "\033[31m copy Error @ ${field[$i]}\033[0m"
  280.             exit 1
  281.         fi
  282.         if [ -e "$bk_file" -a -s "$bk_file" ];then
  283.             echo -e "\033[31m Error $bk_file exist and no empty. \033[0m"
  284.             exit 1
  285.         fi
  286.         mkdir -p $bkpath_whole/$Deep && /bin/cp -f $copied_file $bk_file
  287.         check=$(diff $bk_file $copied_file)
  288.         if [ "$check" == "" ];then
  289.             echo "copy $copied_file => $bk_file"
  290.         else
  291.             echo "error copy @ ${field[$i]}"
  292.         fi
  293.     }
  294. elif [ "X$1" == "Xrcopy" ];then
  295.     if [ "X$2" != "X" ];then
  296.         OLD_IFS="$IFS"
  297.         IFS="#"
  298.         field=($2)
  299.         IFS="$OLD_IFS"
  300.     else
  301.         echo -e "\033[31m rcopy Error \033[0m"
  302.         exit 1
  303.     fi
  304.     for((i=0;i<${#field[@]};i++)){
  305.         if [ "${field[$i]}" == "" ];then
  306.             continue
  307.         fi
  308.         Deep=$(dirname ${field[$i]} >/dev/null)
  309.         rcopied_dir=$confpath/$Deep
  310.         rcopied_file=$confpath/${field[$i]}
  311.         bk_dir=$bkpath_whole/$Deep
  312.         bk_file=$bkpath_whole/${field[$i]}
  313.         if [ ! -d "$bk_dir" -o ! -f "$bk_file" ];then
  314.             echo -e "\033[31m rcopy error $bk_dir not dir or $bk_file not file.\033[0m"
  315.             exit 1
  316.         fi
  317.         if [ ! -s "$bk_file" ];then
  318.             echo -e "\033[31m rcopy error $bk_file exist but empty. \033[0m"
  319.             exit 1
  320.         fi
  321.         if [ ! -d "$rcopied_dir" ];then
  322.             echo -e "\033[31m rcopy error:$rcopied_dir not dir. \033[0m"
  323.             exit 1
  324.         fi
  325.         /bin/cp -f $rcopied_file $rcopied_file.$handle_date || ( echo -e "\033[31mrcopy: backup $rcopied_file failed.\033[0m" && exit 1)
  326.         /bin/cp -f $bk_file $rcopied_file || ( echo -e "\033[31mrcopy: rcopy: restore $rcopied_file failed.\033[0m" && rm -rf $rcopied_file.$handle_date && exit 1)
  327.         check=$(diff $bk_file $rcopied_file)
  328.         if [ "$check" == "" ];then
  329.             echo "restore $bk_file => $rcopied_file"
  330.             rm -rf $rcopied_file.$handle_date
  331.         else
  332.             echo "error rcopy @ ${field[$i]}"
  333.             /bin/cp -f $rcopied_file.$handle_date $rcopied_file
  334.             rm -rf $rcopied_file.$handle_date
  335.         fi
  336.     }
  337. elif [ "X$1" == "Xversion" ];then
  338.     echo "Version:1.0.7"
  339. else
  340.     echo -e "批量备份还原给定目录下的配置文件,可以备份某个文件中的一行或者多行、一个块或者多个块。恢复时,可以直接找到对应的行或者块还原。"
  341.     echo -e "插入字段时,可能精确到具体的某一行"
  342.     echo -e "要被备份的文件格式有两种:"
  343.     echo -e "如:"
  344.     echo -e "pattern_hot_switch=0 #行"
  345.     echo -e "define server_proxy_host1{ #块,块以}作为结束符号"
  346.     echo -e " part1=no1"
  347.     echo -e " part2=no2"
  348.     echo -e " part3=no3"
  349.     echo -e "}"
  350.     echo -e "Help:"
  351.     echo -e "Backup Dir:"
  352.     echo -e "\tServer Conf Dir: $confpath"
  353.     echo -e "\tPartBKP Conf Dir: $bkpath"
  354.     echo -e "\tWholeBKP Conf Dir: $bkpath_whole"
  355.     echo "Usage: $0 [backup|restore|insert|delete|insall|copy|rcopy|version]"
  356.     echo "backup:备份 restore:还原 insert:插入 delete:删除 insall:批量插入 copy:拷贝文件 rcopy:还原拷贝的文件"
  357.     echo -e "\tbackup 'server.config#+src pattern#=request_src_type#...#+src src_acl#'"
  358.     echo -e "\tbackup 'main.config#p_src_switch#url_log_switch#=url_log_switch#'"
  359.     echo -e "\trestore"
  360.     echo -e "\trestore main.config"
  361.     echo -e "\tinsert 'server.config#def p_r t_default#...#r_ww_switch# xxx_xxx_xxx=1-2-3-'"
  362.     echo -e "\tdelete 'server.config#def p_r t_default#...#r_ww_switch#xxx_xxx_xxx'"
  363.     echo -e "\tinsall 'server.config#def p_r t_default#xxx_xxx_xxx=1-2-3-'"
  364.     echo -e "\tcopy 'main.config#r.config#....'"
  365.     echo -e "\trcopy 'main.config#r.config#....'"
  366. fi

阅读(8003) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~