diff Komutu ile İki Dosya Arasındaki Farkları Bulma

diff komutu, iki metin dosyası arasındaki farkları satır satır karşılaştırarak gösterir. Web sunucusu yapılandırma dosyalarında yapılan değişiklikleri takip etmek ve sorunları tespit etmek için vazgeçilmez bir araçtır. Bu yazıda diff komutunun temel kullanımını ve pratik örneklerini bulabilirsiniz.

diff Komutu ile Dosya Farklarini Bulmak: Web Sunucusu Yonetiminde Pratik Rehber

Web sunucusu yonetirken kac kez “bu config dosyasinda ne degisti ki site coktu?” diye sordunuz kendinize? Ya da production ortaminda calisan bir nginx.conf ile staging’deki versiyonu karsilastirmaniz gerekti mi? Iste tam bu noktada diff komutu hayat kurtarici oluyor. Bu yazida diff komutunu web sunucusu yonetimi perspektifinden ele alacagiz, gercek dunya senaryolariyla pratik kullanim ornekleri goreceksiniz.

diff Nedir ve Neden Onemlidir?

diff (difference) komutu, iki dosya arasindaki farklari satir satir karsilastirip size gosteren bir Unix/Linux aracıdir. 1970’lerden bu yana var olan bu komut, basit gorunumune ragmen sistem yoneticisinin en kritik araclarindan biridir.

Web sunucusu yonetiminde diff komutunu en cok su durumlarda kullanirsiniz:

  • Apache veya Nginx yapilandirma dosyalarini karsilastirirken
  • Bir guncelleme oncesi ve sonrasi config farklarini analiz ederken
  • Backup dosyasiyla mevcut dosyayi karsilastirirken
  • Farkli ortamlar (dev, staging, production) arasindaki konfigurasyonlari inceleyken
  • Log dosyalarindaki beklenmedik degisiklikleri tespit ederken
  • Deployment sirasinda hangi dosyalarin degistigini anlayamadigimizda

Temel Kullanim Sontaksi

diff komutunun temel kullanimi son derece basittir:

diff [secenekler] dosya1 dosya2

Cikti okumak ilk basta biraz kafa karistiric gelebilir. Simdi bunu somutlastiralim. Diyelim ki iki basit nginx konfigurasyonunuz var.

eski_nginx.conf:

worker_processes 2;
keepalive_timeout 65;
gzip off;
server_name example.com;

yeni_nginx.conf:

worker_processes 4;
keepalive_timeout 75;
gzip on;
gzip_min_length 1000;
server_name example.com www.example.com;
diff eski_nginx.conf yeni_nginx.conf

Cikti soyle gorunur:

1c1
< worker_processes 2;
---
> worker_processes 4;
2c2
< keepalive_timeout 65;
---
> keepalive_timeout 75;
3c3,4
< gzip off;
---
> gzip on;
> gzip_min_length 1000;
4c5
< server_name example.com;
---
> server_name example.com www.example.com;

Bu ciktida:

  • < isareti birinci dosyadaki (eski) satiri gosterir
  • > isareti ikinci dosyadaki (yeni) satiri gosterir
  • c harfi “change” (degisim) anlamina gelir
  • a harfi “add” (ekleme) anlamina gelir
  • d harfi “delete” (silme) anlamina gelir

Unified Format: Cok Daha Okunabilir Cikti

Normal diff ciktisi biraz ham kalebilir. Web sunucusu configlerini incelerken genellikle unified format kullanmak cok daha mantiklidir. Bu format, git’in de kullandigi formattir ve degisikliklerin etrafindaki context satirlari da gosterir.

diff -u eski_nginx.conf yeni_nginx.conf

Cikti:

--- eski_nginx.conf    2024-01-15 10:23:45.000000000 +0300
+++ yeni_nginx.conf    2024-01-15 14:30:22.000000000 +0300
@@ -1,4 +1,5 @@
-worker_processes 2;
+worker_processes 4;
-keepalive_timeout 65;
+keepalive_timeout 75;
-gzip off;
+gzip on;
+gzip_min_length 1000;
 server_name example.com;
+server_name example.com www.example.com;

Bu formatta:

  • - ile baslayan satirlar eski dosyada var, yenide yok
  • + ile baslayan satirlar yeni dosyada var, eskide yok
  • Boslukla baslayan satirlar her iki dosyada da ayni sekilde mevcut (context)

-u parametresi yerine -U 5 kullanarak kac satir context gostermek istedigini de belirtebilirsiniz:

diff -U 5 eski_nginx.conf yeni_nginx.conf

Gercek Dunya Senaryosu 1: Apache Config Karsilastirma

Diyelim ki bir Apache guncelleme yaptiniz ve sitenin belirli URL’leri duzgun yonlendirmiyor. Backup’inizdaki .conf dosyasiyla mevcut dosyayi karsilastirmak istiyorsunuz.

# Backup dosyasi genellikle su konumlarda olur
diff -u /etc/apache2/sites-available/mysite.conf /etc/apache2/sites-available/mysite.conf.bak

# Ya da tarih damgali backup varsa
diff -u /etc/apache2/sites-available/mysite.conf /backup/apache/mysite.conf.20240115

Eger farklari bir dosyaya kaydetmek istiyorsaniz (ki bunu mutlaka yapmanizi tavsiye ederim):

diff -u /etc/apache2/sites-available/mysite.conf /backup/apache/mysite.conf.20240115 > /tmp/apache_config_diff.patch

# Dosyayi inceleyin
cat /tmp/apache_config_diff.patch

Bu .patch dosyasini daha sonra patch komutuyla uygulamak icin de kullanabilirsiniz, ama bu baska bir yazinin konusu.

Gercek Dunya Senaryosu 2: Dizin Karsilastirma

Web sunucunuzda /etc/nginx/conf.d/ dizinindeki tum config dosyalarini staging sunucusundakiyle karsilastirmak istiyorsunuz. diff komutu tek tek dosyalar icin degil, dizinler icin de calisir.

# Iki dizini recursive olarak karsilastir
diff -rq /etc/nginx/conf.d/ /backup/nginx/conf.d/

-r recursive (alt dizinleri de dahil et), -q ise quiet mode (sadece hangi dosyalarin farkli oldugunu goster, farklar detayli degil) anlamina gelir.

Cikti soyle gorunur:

Files /etc/nginx/conf.d/default.conf and /backup/nginx/conf.d/default.conf differ
Only in /etc/nginx/conf.d/: ssl.conf
Files /etc/nginx/conf.d/proxy.conf and /backup/nginx/conf.d/proxy.conf differ

Bu ciktidan hemen anliyoruz: ssl.conf dosyasi backup’ta yok, default.conf ve proxy.conf farkli. Simdi detaylari gorelim:

# Sadece farkli olan dosyayi detayli incele
diff -u /etc/nginx/conf.d/default.conf /backup/nginx/conf.d/default.conf

# Ya da tum dizini unified formatla karsilastir
diff -ru /etc/nginx/conf.d/ /backup/nginx/conf.d/

Gercek Dunya Senaryosu 3: SSL Sertifika Konfigurasyonu Kontrolu

SSL sertifika yenileme sonrasi Apache virtual host’un dogru guncellendi mi kontrol etmek istiyorsunuz. Eski ve yeni config arasindaki SSL ile ilgili satirlara odaklanmak istiyorsunuz.

# Temel karsilastirma
diff -u /etc/apache2/sites-available/ssl-site.conf.old /etc/apache2/sites-available/ssl-site.conf

# Sadece degisikliklerin sayisini gormek isterseniz
diff /etc/apache2/sites-available/ssl-site.conf.old /etc/apache2/sites-available/ssl-site.conf | wc -l

Bazen whitespace farkliliklari (bosluk, tab gibi) kafa karistirir. Bunlari ignore etmek icin:

# Whitespace farklarini yoksay
diff -u -b /etc/apache2/sites-available/ssl-site.conf.old /etc/apache2/sites-available/ssl-site.conf

# Bos satirlardaki whitespace farklarini da yoksay
diff -u -B /etc/apache2/sites-available/ssl-site.conf.old /etc/apache2/sites-available/ssl-site.conf

# Buyuk-kucuk harf farklarini da yoksay
diff -u -i /etc/apache2/sites-available/ssl-site.conf.old /etc/apache2/sites-available/ssl-site.conf

Gercek Dunya Senaryosu 4: Deployment Scripti ile Entegrasyon

Production deployment yapan bir script dusunun. Hangi config dosyalarinin degistigini log’a yazmak ve operatore bildirmek istiyorsunuz.

#!/bin/bash

# Deployment oncesi config farklarini kontrol eden script
OLD_CONFIG_DIR="/backup/configs/$(date -d 'yesterday' +%Y%m%d)"
NEW_CONFIG_DIR="/etc/nginx"
LOG_FILE="/var/log/deployment/config_diff_$(date +%Y%m%d_%H%M%S).log"

echo "Config farklari kontrol ediliyor..." | tee "$LOG_FILE"
echo "Tarih: $(date)" | tee -a "$LOG_FILE"
echo "==========================================" | tee -a "$LOG_FILE"

# Farkli dosyalari bul
DIFF_OUTPUT=$(diff -rq "$OLD_CONFIG_DIR" "$NEW_CONFIG_DIR" 2>/dev/null)

if [ -z "$DIFF_OUTPUT" ]; then
    echo "Hicbir config dosyasinda degisiklik yok." | tee -a "$LOG_FILE"
else
    echo "Degisen dosyalar:" | tee -a "$LOG_FILE"
    echo "$DIFF_OUTPUT" | tee -a "$LOG_FILE"
    echo "" | tee -a "$LOG_FILE"

    # Her farkli dosya icin detayli diff al
    while IFS= read -r line; do
        if [[ "$line" == Files* ]]; then
            FILE1=$(echo "$line" | awk '{print $2}')
            FILE2=$(echo "$line" | awk '{print $4}')
            echo "--- Detayli fark: $FILE1 ---" | tee -a "$LOG_FILE"
            diff -u "$FILE1" "$FILE2" | tee -a "$LOG_FILE"
            echo "" | tee -a "$LOG_FILE"
        fi
    done <<< "$DIFF_OUTPUT"

    echo "Log dosyasi kaydedildi: $LOG_FILE"
fi

Bu script sayesinde her deployment’ta hangi config’in nasil degistigine dair tam bir kayit tutulmus olur.

Renk ve Gorsel Gelistirmeler: colordiff

Terminal’de renksiz diff ciktisi okumak yorucu olabilir. colordiff aracini yukleyerek cok daha okunabilir bir deneyim elde edebilirsiniz.

# Ubuntu/Debian
sudo apt install colordiff

# CentOS/RHEL
sudo yum install colordiff

# Kullanim aynı diff gibi
colordiff -u /etc/nginx/nginx.conf /backup/nginx/nginx.conf.bak

~/.bashrc veya ~/.bash_aliases dosyasina ekleyerek diff komutunu otomatik olarak renkli hale getirebilirsiniz:

alias diff='colordiff'

Cikti Formatlarini Karsilastirma

diff komutu farkli cikti formatlari destekler. Web sunucusu yonetiminde en cok kullandiginiz formatlar sunlar olacaktir:

  • Normal format (varsayilan): Eski, minimal cikti. Script’lerde parse etmek icin uygun.
  • Unified format (-u): En okunakli format, git de bu formati kullanir. Insan okumasi icin ideal.
  • Context format (-c): Unified’a benzer ama biraz farkli gorunum. Legacy sistem uyumlulugu icin kullanilir.
  • Side by side (-y): Iki dosyayi yan yana gosterir. Genis terminal’de cok kullanisli.
# Side by side karsilastirma
diff -y --width=200 /etc/nginx/nginx.conf /backup/nginx/nginx.conf.bak

# Side by side, sadece farkli satirlari goster
diff -y --suppress-common-lines /etc/nginx/nginx.conf /backup/nginx/nginx.conf.bak

diff ile Binarileri ve Ozet Karsilastirma

Config dosyasi gibi gorunen ama aslinda binary olan (ornegin SSL private key .der formati) ya da cok buyuk log dosyalarini karsilastirirken ozet yontem ise yarar. Burada md5sum veya sha256sum ile kombine kullanmak pratiktir.

# Iki dosyanin hash'ini karsilastir (icerik ayni mi diye bak)
md5sum /etc/nginx/nginx.conf /backup/nginx/nginx.conf.bak

# Ya da dogrudan diff ile binary dosyalari karsilastir (farkli mi degil mi sorar)
diff <(md5sum /etc/nginx/nginx.conf) <(md5sum /backup/nginx/nginx.conf.bak)

Pratik Ipuclari ve Kisayollar

Gunluk is hayatinda isinizi kolaylastiracak birkac ipucu:

Geri donus kodu kontrolu: diff komutu fark buldugunda 1, bulamadiginda 0, hata olustugunda 2 doner. Bunu script’lerde kullanabilirsiniz.

diff dosya1 dosya2
if [ $? -eq 0 ]; then
    echo "Dosyalar ayni"
elif [ $? -eq 1 ]; then
    echo "Dosyalar farkli"
fi

Process substitution ile canli karsilastirma: Bir komutun ciktisini dosyayla karsilastirmak istediginizde:

# Mevcut nginx config ile parse edilmis halini karsilastir
diff <(nginx -T 2>/dev/null | grep -v '#') /etc/nginx/nginx.conf

Recursive, sadece belirli uzantilar: Tum dizini degil, sadece .conf dosyalarini karsilastirmak icin:

# find ile birlikte kullanin
find /etc/nginx -name "*.conf" -exec sh -c 'diff -u "$1" "/backup/nginx${1#/etc/nginx}" 2>/dev/null' _ {} ;

Sonuc

diff komutu, web sunucusu yonetiminin vazgecilmez bir parcasidir. Nginx veya Apache config dosyalarindaki beklenmedik degisiklikleri tespit etmek, deployment oncesi ve sonrasi karsilastirma yapmak, backup kontrolu saglamak gibi pek cok kritik gorevde bu komutu kullanacaksiniz.

En onemli cikartim: diff -u formatini alisinkanlik haline getirin. Unified format hem okunabilir hem de patch komutuyla dogrudan uygulanabilir oldugu icin en pratik secenektir.

Buyuk bir degisiklik yapmadan once her zaman mevcut config’in bir kopyasini alin ve degisiklik sonrasi diff ile karsilastirmayi ihmal etmeyin. Gece 2’de production’da yarim saatlik kesintiye neden olan “kucuk bir bosluk hatasi”nin acisini yasamak istemiyorsaniz, diff komutunu is akisinizin standart bir parcasi haline getirin.

Bir sonraki yazida patch komutuyla diff ciktisini nasil uygulayacagimizi ve bu ikilinin CI/CD pipeline’larinda nasil kullanildigini ele alacagiz.