程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> 關於PHP編程 >> 配置文件智能的備份和還原

配置文件智能的備份和還原

編輯:關於PHP編程

配置文件智能的備份和還原


運用場景:
每當我們為很多安裝同樣的機器升級或者更新服務時,要備份配置文件中的某一行或者多行,或者一個數據塊或者多個數據塊,和服務升級、更新完後,再把對應的備份數據重新寫回新的配置文件中;在大批量的服務器中操作,會浪費很多的時間和精力,以下腳本就是用來完成類似的事情。
主要功能有:
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. ser_client_ip=ipv4
  9. ser_client_len=20*N
  10. ser_client_syn=yes
  11. ser_client_ack=yes
  12. }
以下是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#+srcpattern#=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

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved