bash寫作參考—設定檔異動檢查
在 linux 裡 /etc 這個目錄底下有很多設定檔都是擺在這兒。 /etc 這個目錄關乎整台 Server 運作的正常與否,設定好的話就沒事,若設定錯誤、或是你不小心改錯了設定檔…等等,都會造成 Server 無法正常運作,所以這個目錄的備份很重要。
怎麼備份呢?由於很多程式的設定檔都擱在 /etc 裡,所以我們每天都有可能動到一點這裡面的東西,所以我們就要寫個程式,檢查 /etc 底下的檔案有沒有異動,有就 copy 一份備份並在檔案的最後押上日期,這樣子做的話,我們每天改了什麼東西都會有跡可尋了 ,縱使一時失神改錯了東西,還能去歷史記錄查找以前修改過的記錄,或是被人入侵主機修改了某些設定檔,也能在歷史記錄檔查到修改的痕跡。
本程式需搭配 rsync 使用,沒有的話請自行安裝此程式吧。
本程式的運行環境為 LANG=zh_TW.UTF-8 中文語系,若你的系統為 ubuntu 8.04 以上或 debian 5 lenny 中文環境的話,則無需特殊設定即可運行。檢查方法請下指令 locale 看第一行的設定是否為 LANG=zh_TW.UTF-8
vim /root/backup/cfgchk.sh
#!/bin/bash
# 程式說明:每日檢查/etc系統設定檔,若有異動則備份,並在檔名最後押上日期
# 版本: 2009/08/17 夢見草
#
# 目錄設定說明
# /root/backup/config/compare/ 此為比對目錄,勿動
# /root/backup/config/history/ 此為存放歷史設定檔的目錄
# 第一次執行本程式,有以下設定要做
# 1.須建立一個比對清單,請下指令帶參數,例如: cfgchk.sh newlist
# 2.依你的需求修改路徑變數
#路徑變數設定
compare=/root/backup/config/compare
#請修改你比對目錄存放區,註意:此變數路徑的最後不要加 / 斜線
history=/root/backup/config/history
# ↑ 設定存放歷史設定檔的目錄,註意:此變數路徑的最後不要加 / 斜線
date1=`date +%Y%m%d`
#============ newlist =========================
#製作需備份(比對)清單 cfgBackup.list
if [ "$1" == "newlist" ] ;then
echo 開始產生新的比對清單...
test -d $compare || mkdir -p $compare
#cp /etc/* $compare -R
# 以上指令為沒有裝 rsync 的備用方案
rsync /etc $compare -av -delete
echo 新的比對清單產生完成!
# ↓ 額外的比對清單
#cp `cat cfgBackup.list |grep -v '#'` /root/backup/config/compare/ -R
# grep -v 為去除 # 為首的那一行
#echo `cat list |grep -v '_syscp_'`
fi
#============ newlist =========================
#################################以下開始為比對工作#################################
#
#1.比對工作:檢查目錄存在
#===========檢查 history 裡有沒有存在目錄,沒有的話,則建目錄==============
# 比對 /etc 與 compare/etc 底下的檔案內容差異,若有差異則取出目錄變數後,建目錄
#diff -r /etc/ /root/backup/config/compare/etc/ |grep diff |awk '{printf $3 "\n"}' |sed 's/\(^\/.*\/\)\(.*\)/\1/'
# 以上這行為測試指令,測試變數取得是否正確
for diffDir in `diff -r /etc/ $compare/etc/ |grep diff |awk '{printf $3 "\n"}' |sed 's/\(^\/.*\/\)\(.*\)/\1/'`
do
testExistDir=$history$diffDir
# ↑ 將取出的目錄變數前面加上 要備份的路徑
#echo $OnlyExistDir
#開始檢查目錄存在否,不存在則建目錄
test -d $testExistDir || mkdir -p $testExistDir
done
#比對 /etc 與 compare/etc 底下的檔案存在與否,若compare底下沒有此檔,則取出目錄變數後,建目錄
#適用於在 /etc/ppp/ 新建一個檔案 test.txt 而 compare/etc/ppp/ 沒有 test.txt 此檔的情況下
#diff -r /etc/ /root/backup/config/compare/etc/ |grep "只在" |sed 's/\(^只在 \)\(.*\)\(存在:\)/\2/'|grep ^/etc/ |awk '{printf $1 "\n"}'
# ↑ 取出只在 /etc 的目錄變數
for existDir in `diff -r /etc/ $compare/etc/ |grep "只在" |sed 's/\(^只在 \)\(.*\)\(存在:\)/\2/'|grep ^/etc/ |awk '{printf $1 "\n"}'`
do
OnlyExistDir=$history$existDir
# ↑ 將取出的目錄變數前面加上 要備份的路徑
#echo $testExistDir
#開始檢查目錄存在否,不存在則建目錄
test -d $OnlyExistDir || mkdir -p $OnlyExistDir
done
#指令說明
# ↓ 取出比對後不存在目錄變數的指令
#diff -r /etc/ /root/backup/config/compare/etc/ |grep diff |awk '{printf $3 "\n"}' |sed 's/\(^\/.*\/\)\(.*\)/\1/'
# |sed 's/\(^\/.*\/\)\(.*\)/\1/' →說明: 刪除第一個斜線/到最後一個/斜線以外的內容,以取出路徑名稱
#===========檢查 history 裡有沒有存在目錄,沒有的話,則建目錄==============
#2.比對工作:檢查檔案存在否
#===========只存在於 /etc/ 而不在 $history 內的話,則 copy 一份到 history 裡去備份===========
#diff -r /etc/ /root/backup/config/compare/etc/ |grep "只在" |sed 's/\(^只在 \)\(.*\)\(存在:\)/\2/'|grep ^/etc/ |awk '{printf $1$2 "\n"}'
# 以上這行為測試指令,測試變數取得是否正確
# | sed 's/\(^只在 \)\(.*\)\(存在:\)/\2/' →刪除變中帶的中文字串
# | grep ^/etc/ → 刪除變數中開動的字不是 /etc 的那幾行,
for FileExist in `diff -r /etc/ $compare/etc/ |grep "只在" |sed 's/\(^只在 \)\(.*\)\(存在:\)/\2/'|grep ^/etc/ |awk '{printf $1"/"$2 "\n"}'`
do
cp $FileExist $history$FileExist
done
#===========只存在於 /etc/ 而不在 $history 內的話,則 copy 一份到 history 裡去備份===========
#3.比對工作:異動內容
#===========有異動,則備份並押上日期===================================
#diff -r /etc/ /root/backup/config/compare/etc/ |grep diff |awk '{printf $3 "\n"}'
# 以上這行為測試指令,測試變數取得是否正確
for diffList in `diff -r /etc/ $compare/etc/ |grep diff |awk '{printf $3 "\n"}'`
do
cp -b -S .$date1 $diffList $history$diffList
done
#===========有異動,則備份並押上日期===================================
#echo 工作完成,更新比對目錄
rsync /etc /root/backup/config/compare/ -a -delete
#rm -fr $compare/etc
#cp /etc/* $compare -R
# 以上指令為沒有裝 rsync 的備用方案
然後再此檔做一個連結放入 /etc/cron.daily 裡面去,它就會每天檢查一次了。
chmod 755 /root/backup/cfgchk.sh
ln -s /root/backup/cfgchk.sh /etc/cron.daily/cfgchk
注意:放到 /etc/cron.hourly cron.daily 等目錄裡的執行檔不能有附檔名 .sh 否則它不能正常的執行,這是 debian 系統的 bug
說明一下本程式的運作原理
(1).產生一份比對清單:
就是將現有的 /etc 內容整個 copy 一份到 /root/backup 底下,然後每次檢查時,都比對這兩個目錄的差異性。
(2). #1.比對工作:檢查目錄存在
取出路徑變數,並自動判斷是否要建目錄
由於我們在 /root/backup/config/history 這目錄裡,並不打算放上所有的 /etc 內容,只放有異動過的檔案。這樣在查記錄時才能一目瞭然。
因為在 copy 檔案時不能 copy 到一個不存在的目錄裡去,所以在 copy 前我們就要先檢查history裡的目錄是否存在,若沒有則建立。
(3). #2.比對工作:檢查檔案存在否
有時候我們不一定是修改某些設定檔的內容,而是直接新增一個設定檔。
所以要針對這情況做判斷。 (這種情況就會造成 diff 這個指令在比對差異時會回應不同的訊息)
簡單說就是: 若發現 /etc 底下多了一個檔案的話,則 copy 一份到 history 裡去
(4). #3.比對工作:異動內容
這個工作就是本程式的主要功能了,發現檔案有異動,則 copy 一份到 history 裡去,並在檔名的最後押上日期。
前面那麼多動作,都是為了要排除其它狀況,好讓這個主要的功能正常運行。
(5). 更新比對目錄
整個比對工作完成後,要將 compare 目錄更新到跟 /etc 一樣的狀態,才不會每次比對都不一樣。