Skip to main content

檔案比對 md5

  BUBU 因為公司有在做站台檔案比對確認及通知,這樣子可以確認站台是否有被放置異常的檔案,我是使用 python 加上腳本一起使用,記錄一下日後有機會還可以再使用或者修改

  • 執行掃檔跟產生 md5
#!/usr/bin/python3

import os
import hashlib
import time
import shutil
from pathlib import Path
import fnmatch
import re

# 產生出現當下日期及時間
timestr = time.strftime("%Y%m%d-%H%M%S")

# 要執行檔案確認目錄
path = "要掃的路徑"
# 記錄檔存放目錄
path2 = "記錄檔"
# 當記錄檔目錄不存在會自動產生目錄
if not os.path.isdir(path2):
    os.makedirs(path2)

# 刪除前天的記錄(要填入正確的執行路徑)
os.system("/del.sh")

# 將記錄寫入當下產出的記錄檔
f = open(path2 + "check" + timestr + ".txt", "w")
# 確認 list1 檔案在不在,不存在就會自動建立該檔案(上次的記錄)
destination = Path(path2, "list1.txt")
destination.touch(exist_ok=True)
# 確認 list2 檔案在不在,不存在就會自動建立該檔案(當下的記錄)
destination1 = Path(path2, "list2.txt")
destination1.touch(exist_ok=True)

# 自動計算每個檔案的 md5
def md5_vaule(dir):
    hasher = hashlib.md5()
    afile = open(dir, 'rb')
    buf = afile.read()
    a = hasher.update(buf)
    return str(hasher.hexdigest())

# 要排除的檔案
includes = set(['mp4_service_lock.txt'])
# 要排除的目錄
exclude = set(['sessions'])

# 將 glob 模式轉換為正則表達式
includes = r'|'.join([fnmatch.translate(x) for x in includes])

# 遞迴方式去掃目錄並且產生 md5 寫入到記錄檔裡面
for curDir, dirs, files1 in os.walk(path):
    files1 = [fi for fi in files1 if not re.match(includes, fi)]
    dirs[:] = [d for d in dirs if d not in exclude]
    for file2 in files1:
        file_path = os.path.join(curDir, file2)
        md5 = md5_vaule(file_path)
        print(md5, file_path, file=f)
f.close()

# 宣告記錄檔名稱進行做轉換
f3 = os.path.join(path2, "check" + timestr + ".txt")
f4 = os.path.join(path2, destination)
f5 = os.path.join(path2, destination1)

# 將上次的記錄檔名修改為 list1.txt
dest1 = shutil.copyfile(f5, f4)
# 本次的記錄檔修改為 list2.txt
dest = shutil.copyfile(f3, f5)

# 呼叫另一個 bash 腳本進行確認比對。(要填入正確的執行路徑)
os.system("/diff.sh")
  • 刪除1天前的記錄
#!/bin/bash

# 記錄檔存放目錄
FILE_DIR="記錄檔路徑";

find ${FILE_DIR} -type f -name "check*-*.txt" -mtime +1 -exec rm -rf {} \;
  • 差異比對
#!/bin/bash

# 記錄檔存放目錄
FILE_DIR="記錄檔路徑";

# 建立與前一次程式清單的差異資料。
rm -f "${FILE_DIR}"/tmpA.txt
rm -f "${FILE_DIR}"/tmpB.txt
rm -f "${FILE_DIR}"/new_diff.txt

# 進行檔案比對
diff "${FILE_DIR}"/list1.txt "${FILE_DIR}"/list2.txt |  awk '{print $1,$2,$3,$4,$5}' | grep '< ' |sed 's/< //g' | sort  >> "${FILE_DIR}"/tmpA.txt
diff "${FILE_DIR}"/list1.txt "${FILE_DIR}"/list2.txt |  awk '{print $1,$2,$3,$4,$5}' | grep '> ' |sed 's/> //g' | sort  >> "${FILE_DIR}"/tmpB.txt    

# 讀取 tmpB 檔案
fileB=$(stat -c%s "${FILE_DIR}/tmpB.txt")
if [ ${fileB} == 0 ]; then

	# 讀取 tmpA 分類出為刪除
	cat "${FILE_DIR}"/tmpA.txt |while read line
	do
		string=`echo $line | awk '{print $2}'`
		echo '[del] '${string} >> "${FILE_DIR}"/new_diff.txt
	done

else
	# 讀取 tmpB 分類出編輯或新增
	cat "${FILE_DIR}"/tmpB.txt |while read line
	do
		string=`echo $line | awk '{print $2}'`		
		num=`cat "${FILE_DIR}"/tmpA.txt | grep "${string}" | wc -l`;
		if [ ${num} != 0 ]; then
			echo '[edit] '${string} >> "${FILE_DIR}"/new_diff.txt
		else
			echo '[add] '${string} >> "${FILE_DIR}"/new_diff.txt
		fi
	done
	# 讀取 tmpA 分類出為刪除
	cat "${FILE_DIR}"/tmpA.txt |while read line
	do
			string=`echo $line | awk '{print $2}'`
			num=`cat "${FILE_DIR}"/new_diff.txt | grep "${string}" | wc -l`;
			if [ ${num} == 0 ]; then
					echo '[del] '${string} >> "${FILE_DIR}"/new_diff.txt
			fi
	done
fi

# 發送通知給 line 機器人 
MSG=`tail "${FILE_DIR}"/new_diff.txt`
# echo ${MSG}
if [ "${MSG}" != "" ] ; then
#	echo ${MSG}
	curl -v --header "Authorization: Bearer lineAPIKEY" -d "message=通知主機名稱: ${MSG}" https://notify-api.line.me/api/notify
fi