cmp Komutu ile İkili Dosya Karşılaştırma Rehberi

İki dosyanın gerçekten aynı olup olmadığını anlamanız gerektiğinde, diff komutuna uzanmak ilk içgüdü olabilir. Ama diff metin dosyaları için tasarlanmıştır ve ikili dosyalarla çalışırken size pek yardımcı olmaz. İşte tam bu noktada cmp devreye giriyor. Sessiz, hızlı ve ikili dosya karşılaştırma konusunda son derece yetenekli bu araç, sistem yöneticilerinin araç kutusunda hak ettiği yeri çoğu zaman bulamıyor. Bu yazıda cmp komutunu her yönüyle ele alacağız.

cmp Nedir ve Ne Zaman Kullanılır?

cmp (compare), iki dosyayı byte byte karşılaştıran bir Unix/Linux aracıdır. Metin dosyalarında da çalışır ama asıl gücünü ikili dosyalarda gösterir: firmware imajları, veritabanı dosyaları, arşivler, çalıştırılabilir dosyalar ve disk imajları gibi durumlarda diff yetersiz kalırken cmp size tam olarak nerede farklılık olduğunu söyler.

Temel mantığı şudur: İki dosyayı karşılaştırır, farklılık bulduğunda hangi byte pozisyonunda ve hangi satırda olduğunu raporlar. Dosyalar aynıysa hiçbir şey söylemez (sessiz kalır) ve sıfır çıkış kodu döndürür. Bu davranış özellikle shell scriptlerinde son derece kullanışlıdır.

Ne zaman cmp tercih etmeliyiz?

  • Firmware veya BIOS güncelleme dosyalarını doğrularken
  • Yedekleme dosyalarının orijinalle aynı olup olmadığını kontrol ederken
  • İki disk imajını karşılaştırırken
  • Bir binary’nin beklenmedik şekilde değişip değişmediğini denetlerken
  • Şüpheli bir sistemde kritik dosyaların bütünlüğünü kontrol ederken
  • CI/CD pipeline’larında build artifact’larını doğrularken

Temel Kullanım

En basit haliyle cmp iki argüman alır:

cmp dosya1 dosya2

Eğer dosyalar aynıysa komut hiçbir çıktı vermez ve exit code 0 döner. Farklılarsa ilk farklılığın yerini gösterir:

$ cmp /bin/ls /bin/cp
/bin/ls /bin/cp differ: byte 25, line 1

Bu çıktı bize şunu söylüyor: İki dosya 25. byte’ta farklılaşıyor ve bu farklılık 1. satırda. İkili dosyalar için “satır” kavramı pek anlamlı olmasa da cmp newline karakterlerini sayarak satır bilgisini verir.

Exit code’ları şu şekilde yorumlanır:

  • 0: Dosyalar aynı
  • 1: Dosyalar farklı
  • 2: Hata oluştu (dosya bulunamadı, erişim izni yok vb.)

Parametreler ve Bayraklar

cmp komutunun az ama etkili parametreleri vardır:

-l (–verbose): Tüm farklılıkları listeler, sadece ilkini değil. Her farklı byte için decimal byte pozisyonu ve her iki dosyadaki octal değerleri gösterir.

-s (–silent veya –quiet): Sessiz mod. Hiçbir çıktı vermez, sadece exit code döner. Script’lerde kullanmak için idealdir.

-i N (–ignore-initial=N): Her iki dosyanın başından N byte’ı atlar. Dosyaların başında header bilgisi gibi farklı veriler varsa kullanışlıdır.

-i N:M: İlk dosyanın başından N, ikinci dosyanın başından M byte’ı atlar.

-n N (–bytes=N): Sadece ilk N byte’ı karşılaştırır.

-b (–print-bytes): -l ile birlikte kullanılır. Byte değerlerini ASCII olarak da gösterir.

Kod Örnekleri ile Pratik Kullanım

Örnek 1: Basit Dosya Karşılaştırması

# İki konfigürasyon dosyasının binary olarak aynı olup olmadığını kontrol et
cmp /etc/nginx/nginx.conf /backup/nginx.conf.bak

# Eğer farklıysa çıktı şöyle görünür:
# /etc/nginx/nginx.conf /backup/nginx.conf.bak differ: byte 1024, line 47

Örnek 2: Script İçinde Sessiz Karşılaştırma

Gerçek dünyada cmp en çok -s bayrağıyla shell script’leri içinde kullanılır:

#!/bin/bash

ORIGINAL="/opt/app/binary"
BACKUP="/backup/binary.bak"

if cmp -s "$ORIGINAL" "$BACKUP"; then
    echo "Dosyalar identik, yedek güncel."
else
    echo "UYARI: Dosyalar farklı! Yedek güncellenmesi gerekebilir."
    exit 1
fi

Bu pattern özellikle kritik binary’lerin değişip değişmediğini izleyen monitoring script’lerinde çok işe yarar.

Örnek 3: Tüm Farklılıkları Listeleme

# -l bayrağıyla tüm farklı byte'ları gör
cmp -l dosya1.bin dosya2.bin

# Örnek çıktı:
# 25  60  63
# 26  61  64
# 100 377 0
# Sütunlar: byte_no  dosya1_octal  dosya2_octal

Çıktıyı daha okunabilir hale getirmek için wc -l ile birleştirebilirsiniz:

# Kaç byte farklı olduğunu bul
cmp -l dosya1.bin dosya2.bin | wc -l

Örnek 4: Belirli Byte Aralığını Karşılaştırma

Bir firmware dosyasının sadece belirli bir bölümünü karşılaştırmak istediğinizde:

# İlk 512 byte'ı atla (örneğin MBR header), sonrasını karşılaştır
cmp -i 512 disk_image_v1.img disk_image_v2.img

# Sadece ilk 1024 byte'ı karşılaştır
cmp -n 1024 firmware_old.bin firmware_new.bin

# İlk dosyanın 100. byte'ından, ikinci dosyanın 200. byte'ından başla
cmp -i 100:200 dosya1.bin dosya2.bin

Örnek 5: Disk İmajı Doğrulama

Gerçek bir senaryo: Bir ISO dosyasını yazdıktan sonra USB’deki içeriğin doğru olup olmadığını kontrol etmek:

# USB'ye yazdığınız ISO ile orijinali karşılaştır
# ISO boyutu kadar byte karşılaştır
ISO_SIZE=$(stat -c%s ubuntu-22.04.iso)
cmp -n "$ISO_SIZE" ubuntu-22.04.iso /dev/sdb

if [ $? -eq 0 ]; then
    echo "USB doğrulama başarılı, imaj bütünlüğü korunmuş."
else
    echo "HATA: USB içeriği ISO ile uyuşmuyor!"
fi

Örnek 6: Çoklu Dosya Karşılaştırması

Birden fazla dosyayı bir referansla karşılaştırmak için döngü kullanabilirsiniz:

#!/bin/bash

REFERENCE="/opt/trusted/app_binary"
CHECK_DIR="/opt/deployed/"

echo "Bütünlük kontrolü başlatılıyor..."
FAILED=0

for binary in "$CHECK_DIR"*; do
    filename=$(basename "$binary")
    ref_file="/opt/trusted/$filename"
    
    if [ -f "$ref_file" ]; then
        if ! cmp -s "$binary" "$ref_file"; then
            echo "[UYARI] Değişiklik tespit edildi: $filename"
            FAILED=$((FAILED + 1))
        else
            echo "[OK] $filename"
        fi
    fi
done

if [ $FAILED -gt 0 ]; then
    echo "Toplam $FAILED dosyada değişiklik var!"
    exit 1
else
    echo "Tüm dosyalar bütünlük kontrolünden geçti."
fi

Örnek 7: cmp ile md5sum Kombinasyonu

Büyük dosyalar için önce hash kontrolü, sonra detaylı cmp yaklaşımı performans açısından daha verimli olabilir:

#!/bin/bash

dosya1="$1"
dosya2="$2"

# Önce hızlı hash kontrolü
hash1=$(md5sum "$dosya1" | awk '{print $1}')
hash2=$(md5sum "$dosya2" | awk '{print $1}')

if [ "$hash1" = "$hash2" ]; then
    echo "Hash'ler eşleşiyor, dosyalar aynı."
else
    echo "Hash'ler farklı, detaylı karşılaştırma yapılıyor..."
    # İlk farklılığın nerede olduğunu bul
    cmp "$dosya1" "$dosya2"
    
    # Kaç byte farklı?
    diff_count=$(cmp -l "$dosya1" "$dosya2" | wc -l)
    echo "Toplam $diff_count byte farklı."
fi

Gerçek Dünya Senaryoları

Senaryo 1: Sunucu Güvenlik Denetimi

Bir sabah erken saatte uyarı aldınız: Üretim sunucusunda kritik bir binary değişmiş olabilir. Classik bir file integrity monitoring durumu. cmp burada ilk başvuracağınız araçlardan biri olabilir:

# Güvenilir yedekten kritik sistem binary'lerini karşılaştır
CRITICAL_BINS=("/bin/bash" "/bin/su" "/usr/bin/sudo" "/sbin/sshd")

for bin in "${CRITICAL_BINS[@]}"; do
    backup_path="/secure_backup${bin}"
    if [ -f "$backup_path" ]; then
        if ! cmp -s "$bin" "$backup_path"; then
            echo "KRİTİK UYARI: $bin değiştirilmiş!"
            # Byte seviyesinde fark nerede?
            cmp "$bin" "$backup_path"
        fi
    fi
done

Bu tür kontroller Tripwire veya AIDE gibi araçların yaptığını basit düzeyde taklit ediyor. Küçük ortamlar için hafif ve etkili bir çözüm.

Senaryo 2: Yedekleme Doğrulama

Yedekleme işleri her gece çalışıyor ama yedekler gerçekten sağlam mı? rsync sonrası spot kontrol:

#!/bin/bash
# Yedek doğrulama scripti

SOURCE_DIR="/var/lib/postgresql/data"
BACKUP_DIR="/backup/postgresql/data"

# Kritik dosyaları kontrol et
CRITICAL_FILES=("pg_hba.conf" "postgresql.conf" "PG_VERSION")

for f in "${CRITICAL_FILES[@]}"; do
    if cmp -s "${SOURCE_DIR}/${f}" "${BACKUP_DIR}/${f}"; then
        echo "[OK] $f yedekle uyuşuyor."
    else
        echo "[FAIL] $f yedeği güncel değil veya bozuk!"
    fi
done

Senaryo 3: Firmware Güncelleme Doğrulama

Gömülü sistemler veya ağ ekipmanları üzerinde çalışıyorsanız firmware dosyalarının bütünlüğü kritiktir:

# İndirilen firmware ile checksum doğrulaması yeterli değilse
# İki firmware versiyonunu karşılaştır

FIRMWARE_OLD="router_fw_v2.1.bin"
FIRMWARE_NEW="router_fw_v2.2.bin"

echo "Firmware boyutları:"
ls -la "$FIRMWARE_OLD" "$FIRMWARE_NEW"

echo ""
echo "İlk farklılık noktası:"
cmp "$FIRMWARE_OLD" "$FIRMWARE_NEW"

echo ""
echo "Toplam farklı byte sayısı:"
cmp -l "$FIRMWARE_OLD" "$FIRMWARE_NEW" | wc -l

Bu bilgi özellikle “bu firmware update ne kadar büyük değişiklik içeriyor?” sorusunu cevaplamak için kullanışlıdır.

Senaryo 4: CI/CD Pipeline’da Build Artifact Kontrolü

Deployment öncesi aynı commit’ten üretilen iki build artifact’ın birebir aynı olması gerektiği durumlar (reproducible builds):

#!/bin/bash
# ci_artifact_check.sh

BUILD1="build/output/app_v${BUILD_NUMBER}.tar.gz"
BUILD2="build/output/app_v${BUILD_NUMBER}_verify.tar.gz"

echo "Build artifact doğrulama..."

if cmp -s "$BUILD1" "$BUILD2"; then
    echo "Build reproducible. Deployment onaylandı."
    exit 0
else
    echo "HATA: Build artifact'ları eşleşmiyor!"
    echo "Detay:"
    cmp "$BUILD1" "$BUILD2"
    exit 1
fi

cmp vs Diğer Araçlar

cmp tek seçenek değil elbette, ama her aracın kendi nişi var.

cmp vs diff: diff metin odaklıdır, satır bazlı çalışır ve human-readable fark çıktısı üretir. cmp byte bazlıdır ve ikili dosyalar için tasarlanmıştır. Metin dosyası karşılaştırıyorsanız diff, binary dosya karşılaştırıyorsanız cmp tercih edin.

cmp vs md5sum/sha256sum: Hash’ler sadece “aynı mı, farklı mı” sorusunu cevaplar. cmp buna ek olarak “nerede farklı” sorusunu da cevaplar. Hızlı kontrol için hash, detaylı analiz için cmp kullanın.

cmp vs xxd + diff kombinasyonu: İki binary’nin hex dump’ını alıp diff’lemek cmp -l‘nin yaptığını farklı formatta yapar. Octal yerine hex görmek istiyorsanız bu yaklaşım tercih edilebilir ama cmp çok daha hızlıdır.

cmp vs strings: strings binary’den okunabilir metin dizilerini çıkarır. cmp ise ham byte karşılaştırması yapar. Farklı amaçlar için farklı araçlar.

Performans ve Büyük Dosyalar

cmp büyük dosyalarla çalışırken oldukça verimlidir çünkü ilk farklılığı bulduğu anda durur (varsayılan modda). Ancak -l bayrağıyla tüm farklılıkları tarıyorsanız ve dosya çok büyükse bu işlem zaman alabilir.

Büyük dosyalar için pratik yaklaşım:

# Önce boyutları karşılaştır, aynıysa devam et
size1=$(stat -c%s dosya1.img)
size2=$(stat -c%s dosya2.img)

if [ "$size1" -ne "$size2" ]; then
    echo "Boyutlar farklı: $size1 vs $size2 byte"
    exit 1
fi

# Boyutlar aynıysa cmp ile karşılaştır
# Büyük dosyalar için timeout ekle
timeout 300 cmp -s dosya1.img dosya2.img
exit_code=$?

case $exit_code in
    0) echo "Dosyalar aynı." ;;
    1) echo "Dosyalar farklı." ;;
    124) echo "Zaman aşımı!" ;;
    *) echo "Hata oluştu." ;;
esac

Çok büyük disk imajlarıyla çalışırken (100GB+ gibi) önce md5sum veya sha256sum ile hash kontrolü yapmak daha pratik olabilir. cmp en çok birkaç GB’a kadar olan dosyalarda günlük kullanımda tercih edilir.

İpuçları ve Dikkat Edilmesi Gerekenler

Dosya izinleri: cmp dosya içeriğini karşılaştırır, dosya izinlerini değil. İki dosyanın içeriği aynı olsa bile izinleri farklı olabilir. Bütünlük kontrolü yapıyorsanız izinleri de ayrıca kontrol edin.

Sembolik linkler: cmp sembolik linklerin hedef dosyasını karşılaştırır, linkin kendisini değil. Eğer iki link aynı hedefe işaret ediyorsa cmp onları aynı kabul eder.

Boş dosyalar: İki boş dosya her zaman aynıdır cmp açısından. Beklediğiniz bu değilse dosya boyutunu da kontrol edin.

Standard input kullanımı: - ile stdin’den okuyabilirsiniz:

# Bir komutun çıktısını dosyayla karşılaştır
dd if=/dev/urandom bs=1024 count=1 2>/dev/null | cmp - referans.bin

Exit code kontrolü: Her zaman exit code’u kontrol edin. cmp -s kullanırken bile hata durumunu (exit 2) ayrıca ele almak iyi bir pratiktir.

Sonuç

cmp komutu sade görünümünün arkasında son derece güvenilir bir araçtır. Özellikle güvenlik denetimleri, yedekleme doğrulaması ve ikili dosya bütünlüğü kontrolleri söz konusu olduğunda araç kutunuzda mutlaka bulunmalı. -s bayrağıyla script’lerde koşullu mantık kurmanızı sağlar, -l bayrağıyla byte seviyesinde detaylı analiz yapmanıza imkan tanır.

Her günlük işte kullanacağınız bir komut değil, ama ihtiyaç duyduğunuzda tam olarak ne aradığınızı yapan, beklediğiniz gibi davranan bir araç. Özellikle gece yarısı bir üretim sunucusunda “bu binary değişti mi?” sorusunu hızla cevaplamak istediğinizde, cmp -s ile yazdığınız tek satır sizi çok uzun debug süreçlerinden kurtarabilir.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir