เมื่อระบบปฏิบัติการ Linux (ตระกูล Debian/Ubuntu) ทำงานไปนาน ๆ หรือผ่านการแก้ไขไฟล์คอนฟิกมาอย่างโชกโชน คำถามที่มักตามมาคือ “มีไฟล์ระบบไหนถูกแก้ไข เปลี่ยนแปลง หรือเสียหายไปบ้าง?” โดยปกติเราสามารถใช้คำสั่ง dpkg --verify เพื่อตรวจสอบความสมบูรณ์ของไฟล์ทั้งหมดที่ติดตั้งผ่าน Package Manager ได้ แต่ข้อเสียคือมันจะพ่นข้อมูลออกมาทั้งหมด ซึ่งยากต่อการคัดกรองเฉพาะโฟลเดอร์ที่เราสนใจ (เช่น อยากดูแค่ใน /etc หรือ /usr/bin)
บทความนี้จะแนะนำให้รู้จักกับ verify-pkg-dpkg.sh สคริปต์ที่จะเปลี่ยนให้การตรวจสอบไฟล์ระบบเป็นเรื่องง่าย รวดเร็ว และสามารถกรองเส้นทาง (Path) รวมถึงกำหนดความลึก (Depth) ของไดเรกทอรีได้ตามใจสั่ง!
verify-pkg-dpkg.sh
#!/bin/bash
# ==============================================================================
# Script Name: verify-pkg-dpkg.sh
# Description: High-performance verification using native 'dpkg --verify'.
# Filters results by path and depth efficiently.
# Author : Pitt Phunsanit
# Date : 2026-08-09
# ==============================================================================
# MANUAL & DOCUMENTATION:
#
# OPTIONS:
# -p <path> : Base directory path to filter (Default: /)
# -d <depth> : Maximum directory depth for filtering (Default: Unlimited)
# -h : Display this help message
#
# EXAMPLES:
# sudo ./verify-pkg-dpkg.sh
# sudo ./verify-pkg-dpkg.sh -p /etc
# sudo ./verify-pkg-dpkg.sh -p /usr/bin -d 1
# ==============================================================================
# Ensure script is running with root/sudo privileges
if [ "$EUID" -ne 0 ]; then
echo "❌ Error: Please run this script with root privileges (sudo)."
exit 1
fi
# Enable lastpipe so variables modified inside the while loop persist outside
shopt -s lastpipe
# Get the directory where this script is located
SCRIPT_DIR=$(dirname "$(readlink -f "$0")")
# Default values
SEARCH_PATH="/"
MAX_DEPTH=""
ISO_DATE=$(date +%Y-%m-%d_%H%M%S)
OUTPUT_FILE="${SCRIPT_DIR}/verify-pkg-dpkg-${ISO_DATE}.txt"
# Usage help function
usage() {
echo "Usage: $0 [-p <path>] [-d <depth>]"
echo " -p : Specify starting directory path (Default: /)"
echo " -d : Specify maximum search depth (integer)"
exit 1
}
# Parse command-line arguments
while getopts "p:d:h" opt; do
case ${opt} in
p ) SEARCH_PATH=$OPTARG ;;
d ) MAX_DEPTH=$OPTARG ;;
h | ? ) usage ;;
esac
done
# Ensure SEARCH_PATH ends with a slash for proper matching (except for / itself)
[[ "$SEARCH_PATH" != "/" ]] && SEARCH_PATH="${SEARCH_PATH%/}/"
echo "🔍 Starting high-performance system verification..."
echo "📍 Target Path : $SEARCH_PATH"
[[ -n "$MAX_DEPTH" ]] && echo "↕️ Max Depth : $MAX_DEPTH" || echo "↕️ Max Depth : Unlimited"
echo "📝 Report File : $OUTPUT_FILE"
echo "⚙️ Progress : Processing changed files in real-time..."
echo "---------------------------------------------------------"
# Clean/Create the output file
> "$OUTPUT_FILE"
# Open File Descriptor 3 for direct logging
exec 3>>"$OUTPUT_FILE"
# Function to calculate depth of a file path
get_depth() {
local file_path="$1"
local relative_path="${file_path#$SEARCH_PATH}"
echo "${relative_path}" | tr -cd '/' | wc -c
}
# Counter for items found
MATCH_COUNT=0
# Run native dpkg --verify with unbuffered stream profiling
stdbuf -oL dpkg --verify 2>/dev/null | while read -r LINE; do
FILE_PATH=$(echo "$LINE" | awk '{print $NF}')
# Check if the file is within our target SEARCH_PATH
if [[ "$FILE_PATH" == "$SEARCH_PATH"* || "$SEARCH_PATH" == "/" ]]; then
# If MAX_DEPTH is set, verify the depth limit
if [[ -n "$MAX_DEPTH" ]]; then
CURRENT_DEPTH=$(get_depth "$FILE_PATH")
if (( CURRENT_DEPTH >= MAX_DEPTH )); then
continue
fi
fi
# Print to screen instantly, log to file descriptor, and update counter
echo "$LINE"
echo "$LINE" >&3
((MATCH_COUNT++))
fi
done
exec 3>&-
echo "--------------------------------------------------"
echo "✅ Verification complete!"
echo "⚠️ Total modified files found matching criteria: $MATCH_COUNT"
echo "📂 Results saved to $OUTPUT_FILE"
🛠️ ความสามารถหลัก (Features)
- High Performance: ประมวลผลแบบ Real-time Stream โดยใช้
stdbufทำให้เห็นผลลัพธ์บนหน้าจอทันที ไม่ต้องนั่งรอจนสแกนเสร็จทั้งระบบ - Path Filtering: เลือกเจาะจงสแกนเฉพาะไดเรกทอรีที่ต้องการได้ (เช่น ดูเฉพาะ
/etc) - Depth Control: จำกัดความลึกในการค้นหาได้ เหมาะสำหรับกรณีที่ไม่อยากให้สคริปต์จมลึกลงไปในโฟลเดอร์ย่อยมากเกินไป
- Auto Logging: บันทึกผลลัพธ์ลงไฟล์ Text ให้อัตโนมัติ (แยกตามวันที่และเวลา) เพื่อเอาไปใช้งานต่อหรือส่งให้ทีมตรวจสอบ
📋 ข้อกำหนดก่อนใช้งาน (Prerequisites)
- ระบบปฏิบัติการ: Ubuntu / Debian หรือระบบที่ใช้
dpkg - สิทธิ์การใช้งาน: ต้องรันด้วยสิทธิ์ Root (sudo) เท่านั้น เนื่องจากต้องเข้าถึงไฟล์ระบบที่มีความปลอดภัยสูง
🚀 วิธีการใช้งาน (Usage Guide)
- การเตรียมสคริปต์
นำโค้ดสคริปต์ไปบันทึกไว้ในเครื่อง (เช่น ชื่อไฟล์verify-pkg-dpkg.sh) จากนั้นเปิด Terminal แล้วเปลี่ยนสิทธิ์ให้สคริปต์สามารถรันได้ด้วยคำสั่งchmod +x verify-pkg-dpkg.sh
2. คำสั่งและ Options ที่รองรับsudo ./verify-pkg-dpkg.sh [-p <เส้นทางโฟลเดอร์>] [-d <ระดับความลึก>] [-h]-p: กำหนดไดเรกทอรีเริ่มต้นที่ต้องการตรวจสอบ (หากไม่ใส่ ค่าเริ่มต้นคือ/หรือทั้งระบบ)-d: กำหนดระดับความลึกสูงสุดของโฟลเดอร์ย่อย (หากไม่ใส่ จะค้นหาแบบไม่จำกัด)-h: แสดงข้อความช่วยเหลือ (Help)
💡 ตัวอย่างการใช้งานจริง (Examples)
- ตรวจสอบทั้งระบบ (Default)
หากต้องการตรวจสอบไฟล์ที่มีการเปลี่ยนแปลงทั้งหมดในระบบ ให้รันสคริปต์โดยไม่ใส่ Optionssudo ./verify-pkg-dpkg.sh - ตรวจสอบเฉพาะไฟล์คอนฟิกใน
/etc
หากต้องการดูว่ามีไฟล์คอนฟิกอะไรในโฟลเดอร์/etcถูกแก้ไขไปบ้างsudo ./verify-pkg-dpkg.sh -p /etc - ตรวจสอบเฉพาะไฟล์หลักใน
/usr/bin(จำกัดความลึก)
หากต้องการตรวจสอบไฟล์ใน/usr/binแต่ไม่อยากให้สแกนลึกลงไปในโฟลเดอร์ย่อยอื่น ๆ (ดูแค่ชั้นแรก)sudo ./verify-pkg-dpkg.sh -p /usr/bin -d 1
📝 ผลลัพธ์และการอ่านค่า (Output)
เมื่อสคริปต์ทำงานเสร็จสิ้น ผลลัพธ์จะถูกแสดงบนหน้าจอในรูปแบบสัญลักษณ์รหัสของ dpkg และจะระบุจำนวนไฟล์ที่พบ พร้อมทั้งแจ้งพาธของไฟล์ Log ไว้ที่บรรทัดสุดท้าย
ตัวอย่างผลลัพธ์บนหน้าจอ
🔍 Starting high-performance system verification...
📍 Target Path : /etc/
↕️ Max Depth : Unlimited
📝 Report File : /path/to/script/verify-pkg-dpkg-2026-08-09_233103.txt
⚙️ Progress : Processing changed files in real-time...
---------------------------------------------------------
..5....M c /etc/nginx/nginx.conf
Missing c /etc/cron.d/old-ticker
--------------------------------------------------
✅ Verification complete!
⚠️ Total modified files found matching criteria: 2
📂 Results saved to /path/to/script/verify-pkg-dpkg-2026-08-09_233103.txt
🕵️♂️ วิธีอ่านรหัสความผิดปกติ (Quick Cheat Sheet)
หากคุณเห็นตัวอักษรแปลก ๆ หน้าชื่อไฟล์ เช่น ..5....M หรือ Missing มันคืออะไร?
| รหัส | ความหมาย |
5 | ค่า MD5 checksum ไม่ตรง (เนื้อหาในไฟล์ถูกแก้ไข) |
S | ขนาดของไฟล์ (Size) เปลี่ยนไป |
M | สิทธิ์ของไฟล์ (Permissions/Mode) หรือ Owner ถูกเปลี่ยน |
Missing | ไฟล์นี้หายไปจากระบบ (ถูกลบ) |
📌 ข้อควรระวัง
⚠️ สำคัญมาก: > สคริปต์นี้ทำหน้าที่ “ตรวจจับ” เท่านั้น ไม่ได้ทำการแก้ไขหรือกู้คืนไฟล์ให้ หากคุณพบว่าไฟล์คอนฟิกสำคัญ (เช่น nginx.conf หรือไฟล์ระบบอื่น ๆ) มีความผิดปกติ และคิดจะลง Package ใหม่ทับ ควรทำการ Backup หรือทำ Snapshot ระบบไว้ก่อนเสมอ เพื่อป้องกันไม่ให้ Config ปัจจุบันสูญหายครับ!
อ่านเพิ่มเติม