Linux: الأرشفة والضغط

النسخ الاحتياطي للبيانات هو خط حياة العمليات. في لينكس، tar + gzip هو حل الأرشفة الأكثر شيوعًا، وrsync هو أقوى أداة مزامنة تزايدية.

📋 المتطلبات المسبقة: يجب أن تعرف بالفعل

1. ما ستتعلمه


2. قصة "نسيان معامل الاستثناء"

(1) نقطة الألم: حزم أشياء لا ينبغي حزمها

احتاج شياو مينغ إرسال مجلد مشروع لزميل — الفريق اتفق على عدم نقل مجلدات node_modules و.git لأنها كبيرة جدًا وغير ضرورية.

(2) أمر واحد لأرشيف مثالي

BASH
tar -czf project.tar.gz \
    --exclude=node_modules \
    --exclude=.git \
    --exclude=__pycache__ \
    project/

(3) الفائدة: حزمة نظيفة

انخفض حجم الأرشيف المضغوط لشياو مينغ من 500 ميغابايت (مع node_modules) إلى 2 ميغابايت فقط. زمناؤه استطاع استخدامه فور الاستخراج.


3. نقاط المعرفة

(1) tar — أداة الأرشفة

BASH
# إنشاء أرشيف 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 — ضغط عبر المنصات

TEXT
# ضغط
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 — المزامنة التزايدية

BASH
# الاستخدام الأساسي
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:

(5) ▶ مثال: أرشفة واستخراج بtar

TEXT
# أرشفة دليل المشاريع تحت 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) ▶ مثال: مقارنة خوارزميات الضغط

BASH
# تجهيز بيانات اختبار
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

TEXT
# أرشفة مشروع (مع استثناء أدلة غير مطلوبة)
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

BASH
# نسخ احتياطي محلي
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/

الإخراج:

TEXT
sending 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) ▶ مثال: سكريبت نسخ احتياطي آلي

BASH
#!/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

BASH
#!/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 مشيرًا إلى لقطة اليوم السابق، فتُخزن التغييرات فقط.


📖 ملخص


📝 تمارين

  1. أساسي (⭐): أرشِف ~/projects أو دليل اختبار كـbackup.tar.gz، واستخدم -v لمراقبة العملية، ثم استخدم tar -tf لعرض قائمة الملفات بداخله
  2. متوسط (⭐⭐): استخرج إلى /tmp/test وتأكد من سلامة الملفات، ثم أنشئ دليل اختبار، واضغطه بzip (مع استثناء دليل فرعي)، وفك ضغطه في موقع آخر
  3. متقدم (⭐⭐⭐): استخدم rsync لمزامنة دليل محلي إلى /tmp/backup/، وتأكد من النقل التزايدي (عدّل ملفًا وصاغ المزامنة مجددًا، وراقب أن التغيير فقط نُقل)، ثم اكتب سكريبت نسخ احتياطي يدعم وضعي النسخ الكاملة بـtar.gz والتزايدية بـrsync
Web-Tutorial.com

فريق Web-Tutorial التقني

منصة دروس برمجية يديرها عدة مطورين. كل درس يتم كتابته ومراجعته بواسطة مطورين متخصصين في المجال. نعمل على ضمان دقة وموثوقية المحتوى — إذا لاحظت أي مشكلة، فيرجى إخبارنا.

100%