Linux dünyasında dosya aramak günlük işlerin belki de en sık tekrarlanan parçalarından biri. Bir konfigürasyon dosyasının nerede olduğunu bulmak, birkaç gün önce düzenlediğin log dosyasını bulmak ya da sisteme sızmış şüpheli dosyaları tespit etmek… Tüm bunlar için find komutu adeta biçilmiş kaftan. Ama çoğu sysadmin find komutunu sadece temel düzeyde kullanıyor, oysa bu araç gerçekten güçlü bir silah. Bu yazıda find komutunu en temelinden başlayarak ileri seviye kullanım senaryolarına kadar ele alacağız.
find Komutunun Temel Yapısı
find komutunun söz dizimi ilk bakışta biraz karmaşık görünebilir ama mantığını kavradıktan sonra çok doğal gelmeye başlıyor. Temel yapı şu şekilde:
find [arama_dizini] [seçenekler] [ifade]
Arama dizini belirtmezsen mevcut dizinden başlar. Seçenekler ise aramanın nasıl yapılacağını belirler. Birkaç basit örneğe bakalım:
# Mevcut dizinde "config.txt" dosyasını bul
find . -name "config.txt"
# /etc dizininde "nginx" içeren tüm dosyaları bul
find /etc -name "*nginx*"
# Tüm sistemde "passwd" adlı dosyaları bul (hata mesajlarını görmezden gel)
find / -name "passwd" 2>/dev/null
2>/dev/null kısmını çok sık göreceksin. Bu, izin hatalarını ve erişilemeyen dizin uyarılarını bastırır. Root olmadan geniş çaplı arama yapıyorsan neredeyse zorunlu.
Dosya Türüne Göre Arama
-type parametresi, find komutunun en çok kullanılan seçeneklerinden biri. Sadece dosyaları mı, dizinleri mi yoksa sembolik linkleri mi arıyorsun, bunu belirtmek aramanı ciddi ölçüde hızlandırır.
- -type f: Normal dosyalar
- -type d: Dizinler
- -type l: Sembolik linkler (symlink)
- -type b: Block device dosyaları
- -type c: Character device dosyaları
- -type s: Socket dosyaları
- -type p: Named pipe (FIFO) dosyaları
# Sadece dizinleri bul
find /var/www -type d -name "uploads"
# Sadece sembolik linkleri listele
find /usr/bin -type l
# /tmp altındaki tüm socket dosyalarını bul
find /tmp -type s
Gerçek dünya senaryosu olarak düşün: Web sunucusu üzerinde çalışıyorsun ve uploads klasörlerinin listesini çıkarmak istiyorsun. -type d olmadan arasan, “uploads” adındaki her türlü dosya da sonuçlara karışırdı.
Boyuta Göre Arama
Disk dolunca “hangi dosyalar bu kadar yer kaplıyor?” sorusu kaçınılmaz olarak geliyor. -size parametresi tam bu noktada devreye giriyor.
- -size +100M: 100 MB’dan büyük dosyalar
- -size -10k: 10 KB’dan küçük dosyalar
- -size 1G: Tam olarak 1 GB boyutundaki dosyalar (nadiren kullanılır)
- c: Byte cinsinden
- k: Kilobyte cinsinden
- M: Megabyte cinsinden
- G: Gigabyte cinsinden
# 100 MB'dan büyük dosyaları bul ve boyutlarıyla listele
find / -type f -size +100M -exec ls -lh {} ; 2>/dev/null
# /var/log altında 50 MB'dan büyük log dosyalarını bul
find /var/log -type f -size +50M
# 1 KB'dan küçük boşa işgal eden küçük dosyaları bul
find /home -type f -size -1k
Buradaki -exec ls -lh {} ; kısmına dikkat et. Bu, bulunan her dosya üzerinde ls -lh komutunu çalıştırıyor. {} bulunan dosyanın yolunu temsil eder, ; ise komutun bittiğini belirtir. Bu konuya aşağıda daha detaylı değineceğiz.
Zaman Damgasına Göre Arama
Sistemde son 24 saatte değiştirilmiş dosyaları bulmak, bir güvenlik incelemesi ya da troubleshooting sırasında hayat kurtarıcı olabiliyor.
- -mtime: Son değiştirilme zamanı (içerik)
- -atime: Son erişim zamanı
- -ctime: Son durum değişikliği zamanı (izin, sahip vb.)
- -mmin: Dakika cinsinden değiştirilme zamanı
- -amin: Dakika cinsinden erişim zamanı
# Son 24 saatte değiştirilen dosyalar
find /etc -mtime -1
# Son 7 gün içinde değiştirilen dosyalar
find /var/www/html -type f -mtime -7
# Son 30 dakikada değiştirilen dosyalar
find /tmp -mmin -30
# 30 günden eski log dosyalarını bul
find /var/log -name "*.log" -mtime +30
Şöyle bir senaryo düşün: Sisteme bir şeyler yüklendiğinden şüpheleniyorsun. Son bir saat içinde /tmp ve /var/tmp altında oluşturulmuş çalıştırılabilir dosyaları kontrol etmek mantıklı bir başlangıç noktası olur.
find /tmp /var/tmp -type f -mmin -60 -executable 2>/dev/null
İzinlere ve Sahipliğe Göre Arama
Güvenlik açısından en kritik aramalar bu kategoride. SUID/SGID dosyaları, herkes tarafından yazılabilir dosyalar, belirli kullanıcıya ait dosyalar…
- -perm: Tam izin eşleşmesi
- -perm /izin: Belirtilen izinlerden herhangi biri set edilmiş
- -perm -izin: Belirtilen izinlerin tümü set edilmiş
- -user: Belirli kullanıcıya ait
- -group: Belirli gruba ait
- -nouser: Sahibi olmayan dosyalar (silinmiş kullanıcının dosyaları)
# SUID biti set edilmiş dosyaları bul (güvenlik taraması)
find / -perm -4000 -type f 2>/dev/null
# SGID biti set edilmiş dosyaları bul
find / -perm -2000 -type f 2>/dev/null
# Herkes tarafından yazılabilir dosyalar
find / -perm -0002 -type f 2>/dev/null
# "deploy" kullanıcısına ait tüm dosyalar
find /var/www -user deploy
# Sahibi olmayan dosyalar (orphaned files)
find / -nouser -type f 2>/dev/null
SUID/SGID aramayı rutin güvenlik denetimlerine eklemeni şiddetle tavsiye ederim. Beklenmedik bir SUID dosyası privilege escalation için kullanılabilir.
-exec ile Güçlü Kombinasyonlar
find komutunun asıl gücü, bulduğu dosyalar üzerinde işlem yapabilmesinden geliyor. -exec parametresi bu noktada devreye giriyor.
İki kullanım şekli var:
- -exec komut {} ; : Her dosya için komutu ayrı ayrı çalıştırır
- -exec komut {} + : Bulduğu dosyaları gruplar ve komutu daha az çağırır (daha verimli)
# 30 günden eski log dosyalarını sil
find /var/log -name "*.log" -mtime +30 -exec rm {} ;
# Bulunan tüm .php dosyalarını grep ile tara
find /var/www -name "*.php" -exec grep -l "eval(base64_decode" {} ;
# Bulunan dosyaların izinlerini toplu değiştir
find /var/www/html -type f -exec chmod 644 {} +
# Bulunan dizinlerin izinlerini toplu değiştir
find /var/www/html -type d -exec chmod 755 {} +
Son iki örnek web sunucusu kurulumlarında çok işe yarıyor. Dosyalar 644, dizinler 755 olacak şekilde bir anda tüm web dizinini düzenleyebilirsin.
Daha karmaşık bir örnek verelim. Diyelim ki sunucuda PHP web shell aramak istiyorsun:
find /var/www -name "*.php" -mtime -7 -exec grep -l "system|exec|passthru|shell_exec" {} ;
Bu komut, son 7 günde değiştirilen PHP dosyalarını bulur ve içinde tehlikeli fonksiyonlar geçenleri listeler. Gerçek dünya güvenlik taramasında kullanabileceğin bir şey.
-xargs ile Kullanım
-exec yerine bazen xargs kullanmak daha verimli olabiliyor, özellikle çok sayıda dosya söz konusuysa:
# find çıktısını xargs ile işle
find /var/log -name "*.log" -mtime +30 | xargs rm -f
# Dosya adlarında boşluk olabilirse -print0 ve -0 kullan
find /home -name "*.mp3" -print0 | xargs -0 ls -lh
Dosya adlarında boşluk ya da özel karakter olma ihtimali varsa -print0 ve xargs -0 kombinasyonunu kullanmayı alışkanlık edinmeli. Aksi halde beklenmedik davranışlarla karşılaşabilirsin.
Mantıksal Operatörler ile Birden Fazla Koşul
find komutunda birden fazla koşulu AND, OR, NOT mantığıyla birleştirebilirsin.
- -and veya -a: İki koşulun ikisi de sağlanmalı (varsayılan)
- -or veya -o: Koşullardan en az biri sağlanmalı
- -not veya !: Koşul sağlanmamalı
# Hem .log hem de .txt uzantılı dosyaları bul
find /var -name "*.log" -or -name "*.txt"
# 10 MB'dan büyük VE son 7 günde değiştirilmiş dosyalar
find / -size +10M -and -mtime -7 2>/dev/null
# .conf uzantılı OLMAYAN dosyaları bul
find /etc -type f -not -name "*.conf"
# .php uzantılı ve "admin" adı içermeyen dosyalar
find /var/www -name "*.php" -not -name "*admin*"
Parantez kullanarak daha karmaşık ifadeler de oluşturabilirsin, ama parantezleri ( ve ) şeklinde escape etmen gerekiyor:
find /var/www ( -name "*.php" -or -name "*.html" ) -mtime -3
Derinlik Kontrolü
Bazen belirli bir derinliğe kadar aramak isteyebilirsin. -maxdepth ve -mindepth parametreleri bunu sağlıyor.
- -maxdepth n: En fazla n seviye derinliğe in
- -mindepth n: En az n seviye derinlikten başla
# Sadece mevcut dizinde ara, alt dizinlere girme
find . -maxdepth 1 -type f -name "*.sh"
# Sadece ikinci seviyedeki dizinleri listele
find /home -mindepth 1 -maxdepth 1 -type d
# İlk iki seviyeyi atla, ondan sonrakilerden ara
find /etc -mindepth 2 -maxdepth 3 -name "*.conf"
-maxdepth 1 özellikle çok işe yarıyor. Büyük bir dizin yapısında sadece bir seviyeye bakmak istediğinde tüm alt dizinlerin taranmasını engeller ve çok daha hızlı sonuç alırsın.
Büyük/Küçük Harf Duyarsız Arama
-name büyük/küçük harfe duyarlı çalışır. Bunun yerine -iname kullanırsan büyük/küçük harf farkı gözetmez:
# Hem "Config.txt" hem "config.txt" hem "CONFIG.TXT" bulunur
find /etc -iname "*.conf"
# README dosyalarını harf duyarlılığı olmadan bul
find /home -iname "readme*"
Gerçek Dünya Senaryoları
Teorik bilgi yeterli değil, birkaç gerçek kullanım senaryosuna bakalım.
Senaryo 1: Disk Temizleme
Disk %95 dolu ve neden kaynaklandığını bulmak istiyorsun:
# Önce büyük dosyaları bul
find / -type f -size +500M 2>/dev/null | xargs ls -lh
# 90 günden eski ve büyük log dosyalarını bul
find /var/log -type f -name "*.log" -mtime +90 -size +10M
# Sıkıştırılmış eski log dosyalarını bul
find /var/log -name "*.gz" -mtime +30 -exec ls -lh {} ;
Senaryo 2: Güvenlik Denetimi
Sunucuda rutin güvenlik taraması yapıyorsun:
# World-writable dosyaları tespit et
find / -xdev -type f -perm -0002 2>/dev/null > /tmp/world_writable.txt
# Sahibi olmayan dosyaları bul
find / -xdev ( -nouser -o -nogroup ) 2>/dev/null
# SUID/SGID dosyaların listesini çıkar ve baseline ile karşılaştır
find / -xdev ( -perm -4000 -o -perm -2000 ) -type f 2>/dev/null | sort > /tmp/suid_sgid_$(date +%Y%m%d).txt
Buradaki -xdev parametresi önemli: Aramanın farklı dosya sistemlerine (mount nokttalarına) geçmesini engeller. /proc, /sys gibi sanal dosya sistemlerine girilmesini önler.
Senaryo 3: Web Uygulaması Bakımı
Web sunucusundaki izinleri toplu düzeltmek gerekiyor:
# Tüm dosyaları 644 yap
find /var/www/html -type f -exec chmod 644 {} +
# Tüm dizinleri 755 yap
find /var/www/html -type d -exec chmod 755 {} +
# www-data kullanıcısına ait olmayan dosyaları bul
find /var/www/html -not -user www-data -type f
# PHP dosyası gibi görünen ama .txt uzantılı dosyaları bul
find /var/www/html -name "*.txt" -exec grep -l "<?php" {} ;
Senaryo 4: Yedekleme Scripti
Yedekleme scriptinde belirli dosyaları hariç tutarak arşiv oluşturmak:
# node_modules ve .git hariç tüm dosyaları listele
find /var/www/myapp -type f
-not -path "*/node_modules/*"
-not -path "*/.git/*"
-not -name "*.log"
> /tmp/backup_list.txt
# Bu listeyi tar ile kullanabilirsin
tar czf /backup/myapp_$(date +%Y%m%d).tar.gz -T /tmp/backup_list.txt
Faydalı Ekstra Parametreler
Bilmene değer birkaç parametre daha var:
- -empty: Boş dosya ve dizinleri bulur
- -executable: Çalıştırılabilir dosyaları bulur
- -readable: Okunabilir dosyaları bulur
- -writable: Yazılabilir dosyaları bulur
- -ls: Bulunan dosyaları
ls -dilsformatında listeler - -printf: Özel formatta çıktı almak için
- -prune: Belirli dizinleri aramadan hariç tutar
# Boş dizinleri bul ve sil
find /var/www -type d -empty -delete
# Özel formatta çıktı al (inode, boyut, yol)
find /home -type f -printf "%i %s %pn"
# Cache dizinlerini atlayarak ara
find /var/www -path "*/cache/*" -prune -o -name "*.php" -print
-prune kullanımı biraz alışılması gereken bir syntax. -path "/cache/" -prune ifadesi “bu patha uyanları geç, içine girme” anlamına geliyor. -o ise OR anlamında.
find vs locate
Sık sorulan bir soru: find mi kullanmalıyım, locate mi? Kısa cevap: ikisi farklı amaçlar için.
- locate: Veritabanı tabanlı çalışır, çok hızlıdır ama anlık değildir (updatedb ile güncellenir). Hızlı isim araması için idealdir.
- find: Dosya sistemi üzerinde gerçek zamanlı tarama yapar. Yavaştır ama güncel sonuç verir ve çok daha fazla filtreleme seçeneği sunar.
Bir dosyanın adını hatırlıyor ama nerede olduğunu bilmiyorsan locate ile başla. Zaman, boyut, izin gibi kriterlere göre arama yapman gerekiyorsa find kullan.
Performans İpuçları
find komutunu büyük dosya sistemlerinde çalıştırırken birkaç nokta:
- Arama dizinini mümkün olduğunca dar tut.
/yerine/vargibi daha spesifik bir yol kullan. -maxdepthile derinliği sınırla.-typeile dosya türünü belirt, gereksiz adımları azalt.-xdevile network mount ve sanal dosya sistemlerine girmeyi engelle.- Çok sayıda dosya üzerinde işlem yapacaksan
-exec ... ;yerine-exec ... +veyaxargskullan.
# Yavaş yol
find / -name "*.conf" -exec grep -l "password" {} ;
# Daha hızlı yol
find /etc /home /var -name "*.conf" -exec grep -l "password" {} +
Sonuç
find komutu, Linux sysadmin’liğinin temel taşlarından biri. Temel isim aramasından SUID dosya tespitine, disk temizliğinden web uygulaması bakımına kadar sayısız senaryoda kullanılıyor. Bu kadar geniş bir kullanım alanına sahip olmasının arkasındaki sır, -exec ile birleşince neredeyse sınırsız bir araç haline gelmesi.
Özellikle şu üç kombinasyonu ezberlemen yeterli:
- Güvenlik taraması:
-perm -4000,-nouser,-perm -0002 - Disk yönetimi:
-size +100M,-mtime +30,-empty - Toplu işlem:
-exec chmod {} +,-exec chown {} +
Bunları günlük rutinine katarsan, zamanla find komutunu otomatik refleksle kullanmaya başlarsın. Sonuçta en iyi araç, aklına ilk gelen araçtır.