Linux: الأرشفة والضغط
النسخ الاحتياطي للبيانات هو خط حياة العمليات. في لينكس، tar + gzip هو حل الأرشفة الأكثر شيوعًا، وrsync هو أقوى أداة مزامنة تزايدية.
📋 المتطلبات المسبقة: يجب أن تعرف بالفعل
- الدرس 18: إدارة الحزم
1. ما ستتعلمه
- tar: إنشاء واستخراج الأرشيفات
- خوارزميات ضغط gzip مقابل bzip2 مقابل xz
- zip: ضغط عبر المنصات
- rsync: مزامنة تزايدية
- استراتيجيات نسخ احتياطي آلية
2. قصة "نسيان معامل الاستثناء"
(1) نقطة الألم: حزم أشياء لا ينبغي حزمها
احتاج شياو مينغ إرسال مجلد مشروع لزميل — الفريق اتفق على عدم نقل مجلدات node_modules و.git لأنها كبيرة جدًا وغير ضرورية.
(2) أمر واحد لأرشيف مثالي
tar -czf project.tar.gz \
--exclude=node_modules \
--exclude=.git \
--exclude=__pycache__ \
project/
(3) الفائدة: حزمة نظيفة
انخفض حجم الأرشيف المضغوط لشياو مينغ من 500 ميغابايت (مع node_modules) إلى 2 ميغابايت فقط. زمناؤه استطاع استخدامه فور الاستخراج.
3. نقاط المعرفة
(1) tar — أداة الأرشفة
# إنشاء أرشيف tar
tar -cf archive.tar file1 file2 dir/ # أرشفة
tar -czf archive.tar.gz dir/ # أرشفة + ضغط gzip
> 💡 نصيحة: تذكّر معاملات `tar -czf` — `c` (إنشاء)، و`z` (ضغط gzip)، و`f` (ملف، تحديد اسم الملف). هذا أكثر مزيج شيوعًا؛ الملف الناتج `.tar.gz` هو صيغة التوزيع القياسية في عالم لينكس. للاستخراج، فقط استبدل `c` بـ`x` (استخراج): `tar -xzf`.
tar -cjf archive.tar.bz2 dir/ # أرشفة + ضغط bzip2
tar -cJf archive.tar.xz dir/ # أرشفة + ضغط xz
# استخراج
tar -xf archive.tar # استخراج (يكتشف الصيغة تلقائيًا)
tar -xzf archive.tar.gz # استخراج .tar.gz
tar -xf archive.tar -C /target/dir/ # استخراج إلى دليل محدد
# عرض المحتويات
tar -tf archive.tar.gz # معاينة قائمة الملفات داخل الأرشيف
> ⚠️ تحذير: قبل استخراج أرشيف tar، استخدم `tar -tf` لمعاينة قائمة الملفات — تأكد من عدم وجود "ملفات قنبلة" (مثل ملفات تستخرج أعدادًا ضخمة من الملفات الصغيرة، أو مسارات تبدأ بـ`/` تدل على مسارات مطلقة)، لتجنب الكتابة فوق ملفات النظام أو ملء مساحة القرص.
# استثناء
tar -czf backup.tar.gz --exclude="*.log" --exclude=node_modules dir/
| معامل tar | المعنى |
|---|---|
-c |
إنشاء أرشيف |
-x |
استخراج |
-t |
عرض المحتويات |
-f |
تحديد اسم ملف الأرشيف |
-z |
تصفية عبر gzip |
-j |
تصفية عبر bzip2 |
-J |
تصفية عبر xz |
-v |
عرض الملفات المُعالجة |
-C |
استخراج إلى دليل محدد |
--exclude |
استثناء الملفات المطابقة للنمط |
(2) مقارنة خوارزميات الضغط
| الخوارزمية | الامتداد | المعامل | نسبة الضغط | السرعة | حالة الاستخدام |
|---|---|---|---|---|---|
| gzip | .gz |
-z |
متوسطة | سريعة | النسخ الاحتياطي والتوزيع اليومي |
| bzip2 | .bz2 |
-j |
عالية | بطيئة | عند الحاجة لضغط أعلى |
| xz | .xz |
-J |
الأعلى | الأبطأ | الأرشفة طويلة الأمد، أصغر حجم |
(3) zip/unzip — ضغط عبر المنصات
# ضغط
zip -r project.zip project/ # ضغط دليل بشكل متكرر
zip -r project.zip project/ -x "*.git*" # استثناء .git
zip -r project.zip project/ -P password # تشفير
# استخراج
unzip project.zip # استخراج في الدليل الحالي
unzip project.zip -d /target/dir/ # استخراج إلى دليل محدد
unzip -l project.zip # عرض المحتويات دون استخراج
# مميزات zip: مدعوم أصلاً على كل أنظمة التشغيل
(4) rsync — المزامنة التزايدية
# الاستخدام الأساسي
rsync -av source/ destination/ # مزامنة محلية (متكرر + حفظ الخصائص)
rsync -av --delete source/ dest/ # مزامنة وحذف ملفات في الوجهة غير موجودة في المصدر
> ℹ️ ملاحظة: `rsync --delete` يجعل الوجهة مطابقة تمامًا للمصدر — الملفات في الوجهة التي لا وجود لها في المصدر ستُحذف. إذا أخطأت (مثل مسار مصدر خاطئ)، قد تحذف كمية كبيرة من بيانات الوجهة. أضف دائمًا `--dry-run` أولًا لمعاينة العمليات قبل التنفيذ.
rsync -avz source/ user@host:/dest/ # مزامنة بعيدة (نقل مضغوط)
rsync -avz -e "ssh -p 2222" source/ host:/dest/ # تحديد منفذ SSH
# استثناء
rsync -av --exclude="node_modules" --exclude=".git" src/ dst/
# نسخ احتياطي تزايدية (روابط صلبة)
rsync -av --link-dest=../backup-yesterday/ src/ backup-today/
مميزات rsync:
- نقل تزايدية (يرسل فقط الأجزاء المتغيرة فقط)
- يدعم النقل المضغوط (
-z) - استئناف النقل المقاطع
- نقل آمن عبر SSH
(5) ▶ مثال: أرشفة واستخراج بtar
# أرشفة دليل المشاريع تحت home
tar -czf projects-backup.tar.gz ~/projects/
# عرض محتويات الأرشيف
tar -tf projects-backup.tar.gz | head -10
# استخراج إلى /tmp
tar -xzf projects-backup.tar.gz -C /tmp/
# مع إخراج مفصّل
tar -czvf my-backup.tar.gz --exclude="*.log" /var/log/
(6) ▶ مثال: مقارنة خوارزميات الضغط
# تجهيز بيانات اختبار
mkdir -p /tmp/compress-test
cp -r /usr/share/doc/* /tmp/compress-test/ 2>/dev/null
# gzip
time tar -czf test.tar.gz -C /tmp compress-test
ls -lh test.tar.gz
# bzip2
time tar -cjf test.tar.bz2 -C /tmp compress-test
ls -lh test.tar.bz2
# xz
time tar -cJf test.tar.xz -C /tmp compress-test
ls -lh test.tar.xz
# نتائج المقارنة
# عادةً: test.tar.gz هو الأكبر لكن الأسرع، test.tar.xz هو الأصغر لكن الأبطأ
الإخراج:
TEXT-rw-r--r-- 1 alice alice 1.2M test.tar.gz real 0m0.234s user 0m0.198s sys 0m0.036s -rw-r--r-- 1 alice alice 856K test.tar.bz2 real 0m1.456s user 0m1.389s sys 0m0.067s -rw-r--r-- 1 alice alice 612K test.tar.xz real 0m5.123s user 0m4.987s sys 0m0.136s
(7) ▶ مثال: توزيع عبر المنصات بzip
# أرشفة مشروع (مع استثناء أدلة غير مطلوبة)
cd ~/projects
zip -r myapp.zip myapp/ -x "myapp/node_modules/*" "myapp/.git/*" "myapp/__pycache__/*"
# عرض المحتويات
unzip -l myapp.zip | head -20
# تشفير الأرشيف
zip -r -e secret.zip confidential/ # سيطلب كلمة مرور
(8) ▶ مثال: نسخ احتياطي بrsync
# نسخ احتياطي محلي
rsync -av --delete ~/projects/ /backup/projects/
# نسخ احتياطي بعيد إلى خادم
rsync -avz -e "ssh -i ~/.ssh/mykey" \
--exclude="node_modules" \
--progress \
~/projects/ user@backup-server:/backups/
# نسخ احتياطي تزايدية (باستخدام روابط صلبة)
# اليوم 1
rsync -av /data/ /backup/2026-07-07/
# اليوم 2 (يخزن التغييرات فقط)
rsync -av --link-dest=/backup/2026-07-07/ /data/ /backup/2026-07-08/
الإخراج:
TEXTsending incremental file list sent 1,234 bytes received 512 bytes 2,492.00 bytes/sec total size is 5.6M speedup is 3,210.45 sending incremental file list app.js config.yaml sent 4,567 bytes received 128 bytes 9,390.00 bytes/sec total size is 5.6M speedup is 1,197.23
(9) ▶ مثال: سكريبت نسخ احتياطي آلي
#!/bin/bash
# auto-backup.sh - نسخ احتياطي آلي للأدلة الحرجة
BACKUP_ROOT="/backup"
DATE=$(date +%Y%m%d)
RETENTION_DAYS=30
# أدلة للنسخ الاحتياطي
declare -A DIRS
DIRS["projects"]="$HOME/projects"
DIRS["configs"]="/etc"
DIRS["notes"]="$HOME/notes"
echo "=== Starting backup: $DATE ==="
# إنشاء دليل النسخ الاحتياطي
mkdir -p "$BACKUP_ROOT/$DATE"
for name in "${!DIRS[@]}"; do
src="${DIRS[$name]}"
dest="$BACKUP_ROOT/$DATE/$name.tar.gz"
if [ -d "$src" ]; then
echo "Backing up $src → $dest"
tar -czf "$dest" \
--exclude="node_modules" \
--exclude=".git" \
--exclude="*.log" \
"$src" 2>/dev/null
echo " ✅ $(du -h "$dest" | cut -f1)"
else
echo " ⚠️ Directory does not exist: $src"
fi
done
# حذف النسخ الاحتياطية المنتهية
echo ""
echo "Cleaning backups older than $RETENTION_DAYS days..."
find "$BACKUP_ROOT" -maxdepth 1 -type d -mtime +$RETENTION_DAYS -exec rm -rf {} \;
echo "=== Backup complete ==="
الإخراج:
TEXT=== Starting backup: 20260707 === Backing up /home/alice/projects → /backup/20260707/projects.tar.gz ✅ 12M Backing up /etc → /backup/20260707/configs.tar.gz ✅ 4.5M Backing up /home/alice/notes → /backup/20260707/notes.tar.gz ✅ 256K Cleaning backups older than 30 days... === Backup complete ===
(10) ▶ مثال شامل: حل نسخ احتياطي كامل بrsync
#!/bin/bash
# rsync-backup.sh - نسخ احتياطي تزايدية باستخدام rsync
SOURCE="$HOME/projects/webapp"
DEST_USER="backup"
DEST_HOST="backup.example.com"
DEST_PATH="/backups/webapp"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
LOGFILE="/var/log/backup.log"
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOGFILE"
}
log "Starting backup of $SOURCE..."
# تنفيذ نسخ احتياطي بعيد تزايدية باستخدام rsync
rsync -avz \
--delete \
--partial \
--progress \
--exclude="node_modules" \
--exclude=".git" \
--exclude=".env" \
--exclude="tmp/" \
-e "ssh -i ~/.ssh/backup_key -p 22" \
"$SOURCE/" \
"${DEST_USER}@${DEST_HOST}:${DEST_PATH}/current/" >> "$LOGFILE" 2>&1
if [ $? -eq 0 ]; then
log "✅ Backup succeeded"
# إنشاء لقطة بطابع زمني
ssh -i ~/.ssh/backup_key "${DEST_USER}@${DEST_HOST}" \
"cp -al ${DEST_PATH}/current ${DEST_PATH}/${TIMESTAMP}"
log "✅ Snapshot created: $TIMESTAMP"
else
log "❌ Backup failed (exit code: $?)"
exit 1
fi
❓ أسئلة شائعة
س: ما العلاقة بين tar وgzip؟ ج: tar يتعامل فقط مع الأرشفة (دمج عدة ملفات في ملف واحد)، وليس الضغط. gzip يتعامل مع الضغط. المزيج الشائع
tar -czfيكافئ أرشفة tar ← ضغط gzip. امتدادات الملفات:.tar.gzأو.tgz.
س: ماذا تعني
-cو-zو-fفيtar -czf؟ ج:-c(إنشاء) ينشئ الأرشيف، و-z(gzip) يضغط بـgzip، و-f(ملف) يحدد اسم ملف الأرشيف. يمكن أيضًا كتابةtar -czfبصيغةtar -c -z -f.
س: ما الأفضل للاستخدام عبر المنصات، zip أم tar.gz؟ ج: zip توافق أفضل عبر المنصات — ويندوز/macOS/لينكس كلها تدعمه أصلاً. tar.gz هو المعيار في عالم لينكس/يونكس؛ ويندوز يحتاج أدوات طرف ثالث مثل 7-Zip.
س: ما الذي يجعل rsync أسرع من scp؟ ج: rsync يستخدم خوارزمية نقل تزايدية — يرسل فقط الأجزاء المتغيرة من الملفات. scp ينسخ دائمًا الملفات كاملة. للنقل المتكرر لنفس الملفات مع تغييرات صغيرة، rsync أسرع بكثير.
س: كيف أقوم بنسخ احتياطي تزايدية بدلًا من كاملة؟ ج: rsync بطبيعته ينقل فقط الزيادات (الأجزاء المتغيرة). مدمجًا مع
--link-destلإنشاء لقطات روابط صلبة: التشغيل الأول كامل، ثم كل يوم استخدم--link-destمشيرًا إلى لقطة اليوم السابق، فتُخزن التغييرات فقط.
📖 ملخص
tar -czfأرشفة وضغط، وtar -xfاستخراج، وtar -tfعرض المحتويات--excludeيستثني الملفات غير المطلوبة- gzip الأسرع، وxz الأفضل في نسبة الضغط، وzip الأكثر توافقًا عبر المنصات
rsync -avzمزامنة تزايدية، و--deleteيحذف الملفات الزائدة في الوجهة--link-destينشئ لقطات تزايدية قائمة على روابط صلبة
📝 تمارين
- أساسي (⭐): أرشِف
~/projectsأو دليل اختبار كـbackup.tar.gz، واستخدم-vلمراقبة العملية، ثم استخدمtar -tfلعرض قائمة الملفات بداخله - متوسط (⭐⭐): استخرج إلى
/tmp/testوتأكد من سلامة الملفات، ثم أنشئ دليل اختبار، واضغطه بzip (مع استثناء دليل فرعي)، وفك ضغطه في موقع آخر - متقدم (⭐⭐⭐): استخدم rsync لمزامنة دليل محلي إلى
/tmp/backup/، وتأكد من النقل التزايدي (عدّل ملفًا وصاغ المزامنة مجددًا، وراقب أن التغيير فقط نُقل)، ثم اكتب سكريبت نسخ احتياطي يدعم وضعي النسخ الكاملة بـtar.gz والتزايدية بـrsync