Yıllarca sistem yöneticiliği yaptıktan sonra şunu kesinlikle söyleyebilirim: find ve xargs kombinasyonunu öğrendiğiniz gün, terminalde geçirdiğiniz zamanın kalitesi dramatik biçimde değişiyor. Onlarca, yüzlerce, hatta binlerce dosya üzerinde tek satırda işlem yapabilmek, script yazmaya gerek kalmadan karmaşık görevleri tamamlamak – bu ikili bunu mümkün kılıyor. Bu yazıda gerçek dünya senaryolarıyla bu kombinasyonu derinlemesine inceleyeceğiz.
find ve xargs Neden Bu Kadar Güçlü?
find komutu tek başına zaten oldukça yetenekli. Dosyaları isme göre, boyuta göre, tarihe göre, izinlere göre bulabiliyorsunuz. Ama bulduğunuz dosyalarla ne yapacaksınız? find‘ın -exec seçeneği var tabii, ama büyük dosya listeleriyle çalışırken xargs çok daha verimli ve esnek bir çözüm sunuyor.
Temel fark şu: -exec her dosya için ayrı bir process başlatıyor. 10.000 dosyanız varsa 10.000 kez komut çalıştırıyor. xargs ise bulduğu dosyaları gruplar halinde işleyerek çok daha az process başlatıyor. Büyük ölçekli işlemlerde bu fark ciddi performans kazanımı anlamına geliyor.
xargs‘ın temel çalışma mantığı basit: standart girişten (stdin) aldığı veriyi, belirttiğiniz komuta argüman olarak ekliyor. find‘dan gelen dosya listesini xargs‘a pipe (|) ile gönderdiğinizde, xargs bu listeyi alıp istediğiniz komuta toplu olarak besliyor.
Temel Kullanım: İlk Adımlar
En basit haliyle şöyle çalışıyor:
find /var/log -name "*.log" | xargs ls -lh
Bu komut /var/log altındaki tüm .log uzantılı dosyaları bulup ls -lh ile listeler. Ama burada önemli bir problem var: dosya adlarında boşluk karakteri varsa bu komut hata verir veya yanlış çalışır.
Bu yüzden altın kural şu: find ile xargs kullanırken her zaman null karakter ayırıcı kullanın:
find /var/log -name "*.log" -print0 | xargs -0 ls -lh
-print0 seçeneği dosya adlarını newline yerine null karakterle ayırıyor. xargs -0 ise null karakteri ayırıcı olarak kullanıyor. Dosya adında boşluk, özel karakter, hatta newline bile olsa sorunsuz çalışıyor. Bunu bir alışkanlık haline getirin, ileride başınız ağrımaz.
Temel xargs Parametreleri
Devam etmeden önce xargs‘ın en çok kullanılan parametrelerini tanıyalım:
- -0: Null karakter ayırıcı kullanır (find -print0 ile birlikte)
- -I {}: Argümanın komut içindeki yerini belirler, her argüman için ayrı çalışır
- -P N: N kadar paralel process başlatır
- -n N: Her komuta en fazla N argüman gönderir
- -t: Çalıştırılan komutları ekrana yazdırır (debug için harika)
- –no-run-if-empty: Giriş boşsa komutu çalıştırmaz
- -L N: Her komut için en fazla N satır kullanır
Gerçek Dünya Senaryosu 1: Log Temizliği
Üretim sunucusunda disk dolmaya başladı, eski log dosyalarını temizlemeniz gerekiyor. Ama dikkatli olmanız lazım, yanlışlıkla kritik bir şeyi silmeyin.
Önce ne sileceğinizi görün, sonra silin:
# Önce 30 günden eski .log dosyalarını listele
find /var/log/myapp -name "*.log" -mtime +30 -print0 | xargs -0 ls -lh
# Toplamda ne kadar yer kaplıyorlar?
find /var/log/myapp -name "*.log" -mtime +30 -print0 | xargs -0 du -ch | tail -1
# Güvenliyse sil
find /var/log/myapp -name "*.log" -mtime +30 -print0 | xargs -0 rm -v
-v parametresi rm‘ye silinen her dosyayı ekrana yazdırmasını söylüyor. Toplu işlem yaparken bu tür geri bildirimler çok değerli.
Burada find‘ın zaman parametrelerini de hatırlatayım:
- -mtime +30: Son değiştirilme tarihi 30 günden eski
- -mtime -7: Son 7 gün içinde değiştirilmiş
- -atime +90: Son erişim tarihi 90 günden eski
- -newer dosya.txt: dosya.txt’den daha yeni
Gerçek Dünya Senaryosu 2: Toplu Dosya İzin Düzeltmesi
Web sunucusuna yeni dosyalar yüklendi ama izinler karışık. PHP dosyaları 644, dizinler 755 olmalı. Bunu elle yapmak saatler alır.
# Tüm PHP dosyalarını 644 yap
find /var/www/html -type f -name "*.php" -print0 | xargs -0 chmod 644
# Tüm dizinleri 755 yap
find /var/www/html -type d -print0 | xargs -0 chmod 755
# Belirli bir kullanıcıya ait olan ama yanlış izinli dosyaları bul ve düzelt
find /var/www/html -user www-data -type f -not -perm 644 -print0 | xargs -0 chmod 644
Bu işlem binlerce dosya içeren bir web sitesinde elle dakikalar, hatta saatler sürecek bir işi saniyeler içinde tamamlıyor.
-I {} Parametresi: Argümanın Yerini Belirlemek
Bazen dosya adını komutun sonuna değil, ortasına veya belirli bir yere koymak istiyorsunuz. İşte -I {} tam bu iş için:
# Her dosyayı ayrı bir dizine kopyala
find /backup -name "*.conf" -print0 | xargs -0 -I {} cp {} /etc/backup-configs/
# Dosyaları tarihle yeniden adlandır
find /home/deploy -name "*.sql" -print0 | xargs -0 -I {} mv {} {}.bak
# Her config dosyası için yedek al
find /etc/nginx -name "*.conf" -print0 | xargs -0 -I {} bash -c 'cp {} {}.$(date +%Y%m%d)'
{} placeholder olarak çalışıyor, xargs bunu otomatik olarak bulunan dosya adıyla değiştiriyor. -I {} kullandığınızda her argüman için ayrı ayrı komut çalışıyor, bu -n 1 ile aynı anlama geliyor.
Paralel İşlem: -P Parametresi ile Hız Kazanmak
Modern sunucularda birden fazla CPU çekirdeği var ve biz tek thread’de çalışarak bu kaynakları boşa harcıyoruz. xargs -P ile paralel işlem yapabilirsiniz:
# 4 paralel process ile dosyaları sıkıştır
find /data/logs -name "*.log" -mtime +7 -print0 | xargs -0 -P 4 gzip
# 8 core'lu sunucuda resim optimizasyonu
find /var/www/uploads -name "*.jpg" -print0 | xargs -0 -P 8 -I {} jpegoptim --max=85 {}
# Paralel md5 hash hesaplama (büyük dosya koleksiyonları için)
find /backup -name "*.tar.gz" -print0 | xargs -0 -P 4 md5sum > checksums.txt
Kaç paralel process açacağınızı belirlerken CPU çekirdek sayısını aşmamaya dikkat edin. CPU-bound işlemler için nproc komutunun çıktısını kullanabilirsiniz:
find /data -name "*.csv" -print0 | xargs -0 -P $(nproc) -I {} python3 /scripts/process.py {}
Gerçek Dünya Senaryosu 3: Güvenlik Taraması
Sysadmin olarak arada bir sunucularda güvenlik denetimleri yapmanız gerekiyor. SUID bit’i olan dosyalar, dünyaya yazılabilir dosyalar, sahipsiz dosyalar – bunlar güvenlik açığı işareti olabilir.
# SUID bit'i olan tüm dosyaları listele
find / -xdev -type f -perm -4000 -print0 | xargs -0 ls -lh 2>/dev/null
# Dünyaya yazılabilir (world-writable) dosyaları bul
find /var/www -type f -perm -o+w -print0 | xargs -0 ls -la
# Sahipsiz (orphaned) dosyaları bul
find /home -nouser -o -nogroup 2>/dev/null | xargs ls -la
# .htaccess dosyalarını kontrol et (izinsiz ekleme olabilir)
find /var/www -name ".htaccess" -newer /var/www/html/index.php -print0 | xargs -0 ls -la
Bu kontrolleri cron job’a ekleyip sonuçları mail ile almanız iyi bir güvenlik pratiği.
Metin İşlemleri: grep ile Kombinasyon
find, xargs ve grep üçlüsü log analizi ve kod taraması için müthiş bir araç seti oluşturuyor:
# Tüm PHP dosyalarında SQL injection için şüpheli pattern ara
find /var/www -name "*.php" -print0 | xargs -0 grep -l "eval(base64_decode"
# Config dosyalarında plaintext şifre ara
find /etc -name "*.conf" -print0 | xargs -0 grep -i "passwords*=" 2>/dev/null
# Son 24 saatte değişen dosyalarda belirli string ara
find /var/www -mtime -1 -type f -print0 | xargs -0 grep -l "malware_string"
# Birden fazla dizinde aynı anda arama yap
find /home /var/www /opt -name "*.py" -print0 | xargs -0 grep -n "import os; os.system"
grep -l sadece eşleşen dosya adlarını veriyor, -n satır numaralarını gösteriyor. Büyük kod tabanlarında bu kombinasyon IDE‘lerin arama özelliğinden çok daha hızlı çalışıyor.
Gerçek Dünya Senaryosu 4: Backup ve Arşivleme
Belirli dosyaları tarball’a eklemek ya da uzak sunucuya kopyalamak için:
# 1 haftadan eski ve 100MB'dan büyük log dosyalarını arşivle
find /var/log -name "*.log" -mtime +7 -size +100M -print0 |
xargs -0 tar -czf /backup/old-logs-$(date +%Y%m%d).tar.gz
# Değişen config dosyalarını yedek sunucuya rsync ile gönder
find /etc -name "*.conf" -newer /tmp/last-backup-time -print0 |
xargs -0 -I {} rsync -az {} backup-server:/etc-backup/
# Belirli uzantılı dosyaları koruyarak sıkıştır
find /data/reports -name "*.csv" -mtime +30 -print0 |
xargs -0 -P 2 gzip -9
Backup scriptlerinde find -newer referans_dosya tekniği çok kullanışlı. Referans dosyanın son değiştirilme tarihinden daha yeni dosyaları bulup işlemenizi sağlıyor.
-n Parametresi ile Batch Size Kontrolü
Bazı komutlar çok fazla argümanla çağrıldığında “Argument list too long” hatası veriyor. xargs -n ile kaç argüman gönderileceğini sınırlayabilirsiniz:
# Her seferinde en fazla 100 dosya işle
find /var/www -name "*.php" -print0 | xargs -0 -n 100 php -l
# Her seferinde tek bir dosya işle (-n 1, -I {} olmadan)
find /tmp -name "*.tmp" -print0 | xargs -0 -n 1 shred -vzu
# Batch halinde dosyaları bir script'e gönder
find /data -name "*.json" -print0 | xargs -0 -n 50 python3 /scripts/bulk-process.py
-t Parametresi ile Debug Modu
Karmaşık xargs komutlarını çalıştırmadan önce ne yapacaklarını görmek isteyebilirsiniz:
# -t ile çalıştırılacak komutları gör
find /home -name "*.txt" -print0 | xargs -0 -t rm -v
# --no-run-if-empty ile boş liste güvenliği
find /tmp -name "*.sock" -mtime +1 -print0 | xargs -0 --no-run-if-empty rm -v
-t her komutun stderr’e yazdırılmasını sağlıyor, bu sayede neyin çalıştığını canlı takip edebiliyorsunuz. Özellikle production’da bir script ilk kez çalıştırılıyorsa bu güvence çok önemli.
İleri Seviye: bash -c ile Karmaşık İşlemler
Bazen tek bir komut yetmez, birden fazla işlemi bir arada yapmak istersiniz. bash -c burada devreye giriyor:
# Her dosya için log kaydı alarak işlem yap
find /var/www -name "*.php" -newer /tmp/deploy-time -print0 |
xargs -0 -I {} bash -c 'echo "Processing: {}" >> /var/log/deploy.log && php -l "{}"'
# Dosyayı işle ve sonucu kaydet
find /data/input -name "*.csv" -print0 |
xargs -0 -P 4 -I {} bash -c
'filename=$(basename {} .csv); python3 /scripts/convert.py {} > /data/output/${filename}.json'
# Dosyaları boyutlarıyla birlikte logla
find /backup -name "*.tar.gz" -mtime +90 -print0 |
xargs -0 -I {} bash -c 'size=$(du -sh {} | cut -f1); echo "Deleting {} ($size)"; rm {}'
bash -c kullandığınızda dikkatli olun: {} içinde özel karakterler varsa alıntılama (quoting) konusunda ekstra dikkatli olmanız gerekiyor. Güvenli bir alternatif olarak bir fonksiyon tanımlayıp export edebilirsiniz:
# Fonksiyon tanımla ve export et
process_file() {
local file="$1"
echo "Processing: $file"
gzip -9 "$file"
}
export -f process_file
# xargs ile çağır
find /data/logs -name "*.log" -mtime +7 -print0 |
xargs -0 -P 4 -I {} bash -c 'process_file "$@"' _ {}
find ile Boyut Filtresi Kombinasyonu
Disk yönetimi için boyut filtresi çok kritik:
# 500MB'dan büyük dosyaları bul ve listele
find / -xdev -size +500M -print0 | xargs -0 du -sh | sort -rh
# 0 byte'lık boş dosyaları temizle
find /tmp -type f -empty -print0 | xargs -0 rm -v
# 100KB'dan küçük log dosyalarını birleştir ve arşivle
find /var/log/old -name "*.log" -size -100k -print0 |
xargs -0 cat >> /var/log/archive/merged-small-logs.txt
Pratik İpuçları ve Sık Yapılan Hatalar
Yıllarca bu araçları kullanırken öğrendiğim bazı kritik noktalar:
Her zaman önce test edin: rm veya chmod gibi geri alınamaz işlemler yapmadan önce ls veya echo ile test yapın.
# Önce ne silineceğini gör
find /tmp -name "*.tmp" -mtime +1 -print0 | xargs -0 echo
# Tamam görünüyorsa sil
find /tmp -name "*.tmp" -mtime +1 -print0 | xargs -0 rm -v
find -maxdepth ile derinliği sınırla: Çok derin dizin yapılarında performans için önemli.
find /var/www -maxdepth 3 -name "*.log" -print0 | xargs -0 gzip
-xdev ile filesystem sınırı koru: / üzerinde arama yaparken mount point’leri atlamak için.
find / -xdev -name "core" -print0 | xargs -0 rm -v
Hata çıktısını yönet: /proc gibi özel dizinlerden gelen hata mesajlarını bastırın.
find / -name "*.conf" 2>/dev/null -print0 | xargs -0 grep -l "deprecated"
Sonuç
find ve xargs kombinasyonu, sistem yönetiminde elle yapılması saatler sürecek işleri dakikalara, hatta saniyelere indiriyor. Temel kullanımdan paralel işleme, log temizliğinden güvenlik taramasına kadar kullanım alanı son derece geniş. Bu araçlara hakim olmak, bir sysadmin olarak üretkenliğinizi ciddi anlamda artırıyor.
Öğrendiğiniz bu teknikler için önerim: hemen production’da denemeyin. Önce bir test ortamında ya da /tmp altında pratik yapın. Özellikle rm, chmod, chown gibi kalıcı etkisi olan komutları xargs ile kullanırken -t ile önce ne yapıldığını görün.
Son bir not olarak: bu komutların gücü aynı zamanda tehlikesidir. Yanlış yazılmış bir find | xargs rm komutu binlerce dosyayı saniyeler içinde silebilir. Bu yüzden her zaman “önce listele, sonra işlem yap” prensibini benimseyin. Ama bir kez alıştığınızda bu araçlardan vazgeçemeyeceksiniz.