Sistem yöneticiliğinde en sık karşılaşılan durumlardan biri şudur: bir süreç neden bu kadar disk kullanıyor, hangi port açık ve kim kullanıyor, sildiğim dosya neden hâlâ disk alanı kaplıyor? İşte tam bu noktada lsof komutu devreye giriyor. “List Open Files” anlamına gelen bu araç, Linux’ta her şeyin bir dosya olduğu felsefesinin pratik yansımasıdır. Soketler, pipe’lar, dizin tanıtıcıları, cihaz dosyaları… hepsi lsof ile izlenebilir.
lsof Nedir ve Neden Bu Kadar Güçlüdür?
Linux çekirdeği perspektifinden bakıldığında bir ağ soketi de, bir log dosyası da, bir terminal bağlantısı da birer “dosya tanıtıcısıdır” (file descriptor). lsof bu tanıtıcıların tamamını listeleyebilir. Bu yüzden sadece “hangi dosyalar açık?” sorusunu değil, “hangi portlar dinleniyor, hangi süreç hangi ağ bağlantısını tutuyor, silinen ama hâlâ kullanılan dosyalar var mı?” gibi kritik soruları da yanıtlayabilir.
Çoğu Linux dağıtımında lsof kurulu gelir. Gelmiyorsa:
# Debian/Ubuntu
sudo apt install lsof
# RHEL/CentOS/Rocky
sudo dnf install lsof
# Arch Linux
sudo pacman -S lsof
lsof çıktısını anlamak için önce sütun yapısını kavramak gerekiyor:
- COMMAND: Dosyayı açan sürecin adı
- PID: Süreç kimliği
- USER: Dosyayı açan kullanıcı
- FD: Dosya tanıtıcı tipi (cwd, txt, mem, 0u, 1w, 2u vb.)
- TYPE: Dosya tipi (REG, DIR, CHR, IPv4, IPv6, unix vb.)
- DEVICE: Aygıt numarası
- SIZE/OFF: Dosya boyutu veya offset
- NODE: Inode numarası
- NAME: Dosyanın tam yolu veya soket bilgisi
Temel Kullanım: İlk Komutlar
Parametresiz çalıştırdığınızda lsof sistemdeki tüm açık dosyaları döker. Bu genellikle binlerce satır üretir ve çıktıyı grep veya diğer filtrelerle birleştirmek zorunlu hale gelir.
# Tüm açık dosyaları listele (root yetkisi önerilir)
sudo lsof | head -50
# Kaç tane açık dosya var sistemde?
sudo lsof | wc -l
Sıkça kullanılan temel parametreler:
- -p PID: Belirli bir sürecin açık dosyalarını gösterir
- -u kullanici: Belirli kullanıcının açık dosyalarını gösterir
- -i: Ağ bağlantılarını ve soketleri listeler
- -t: Sadece PID numaralarını çıktı olarak verir (script’lerde kullanışlı)
- -n: DNS çözümlemesini devre dışı bırakır (hız kazanımı)
- -P: Port numaralarını servis ismine çevirmez
- +D dizin: Belirtilen dizinde açık olan tüm dosyaları gösterir
- -c komut: Belirtilen komut adıyla eşleşen süreçlerin dosyalarını gösterir
- -a: Birden fazla filtre arasında AND mantığı kurar (varsayılan OR’dur)
- -r saniye: Belirtilen aralıkla tekrar eden izleme modu
Süreç Bazlı Dosya Takibi
Bir sürecin tam olarak neye eriştiğini anlamak, troubleshooting’in temel adımıdır. Nginx’in hangi dosyaları açık tuttuğunu görmek istiyorsunuz diyelim:
# PID ile süreç dosyalarını listele
sudo lsof -p 1234
# Komut adıyla (tüm nginx süreçleri)
sudo lsof -c nginx
# Birden fazla PID için virgülle ayır
sudo lsof -p 1234,5678,9012
Gerçek dünya senaryosu: Bir uygulama sunucusunda “too many open files” hatası aldığınızda, o sürecin kaç dosya tanıtıcısı kullandığını hızlıca kontrol edebilirsiniz:
# Belirli bir sürecin açık dosya sayısını öğren
sudo lsof -p 3421 | wc -l
# Sistemdeki açık dosya limitini kontrol et
cat /proc/sys/fs/file-max
# Süreç bazlı limiti kontrol et
cat /proc/3421/limits | grep "open files"
Ağ Soketleri ve Port Takibi
lsof‘un en çok kullanıldığı alan budur. Özellikle bir port üzerinde zaten bir şey çalışıyor mesajı aldığınızda kim o portu kullanıyor sorusu hayat kurtarır.
# Tüm ağ bağlantılarını listele
sudo lsof -i
# Sadece TCP bağlantıları
sudo lsof -i TCP
# Sadece UDP
sudo lsof -i UDP
# Belirli bir port numarasını kullanan süreci bul
sudo lsof -i :80
sudo lsof -i :443
# Port aralığı (80'den 8080'e kadar)
sudo lsof -i :80-8080
# Hem IPv4 hem IPv6 bağlantıları ayrı ayrı
sudo lsof -i 4
sudo lsof -i 6
Gerçek Senaryo 1: “8080 portu meşgul” hatası
Yeni bir uygulama deploy etmeye çalışıyorsunuz, port 8080’in kullanımda olduğunu söylüyor. Şu şekilde yaklaşın:
# Port 8080'i kim kullanıyor?
sudo lsof -i :8080 -n -P
# Çıktı örneği:
# COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
# java 2341 tomcat 52u IPv6 45231 0t0 TCP *:8080 (LISTEN)
# Sadece PID'i al ve süreci sonlandır
sudo kill $(sudo lsof -t -i :8080)
Dinleme durumundaki (LISTEN) portları filtrelemek için:
# Sadece LISTEN durumundaki portları göster
sudo lsof -i -s TCP:LISTEN -n -P
# Belirli bir IP adresine giden bağlantılar
sudo lsof -i @192.168.1.100
# Belirli bir IP ve port kombinasyonu
sudo lsof -i @192.168.1.100:3306
Kullanıcı Bazlı İzleme
Güvenlik olayı incelemesi veya kaynak kullanımı analizi sırasında belirli kullanıcının tam olarak ne yaptığını görmek gerekebilir:
# Belirli kullanıcının açık dosyaları
sudo lsof -u www-data
# Birden fazla kullanıcı
sudo lsof -u ali,mehmet
# Belirli kullanıcı HARİÇ herkesi göster
sudo lsof -u ^root
# Kullanıcının ağ bağlantılarını AND ile filtrele
sudo lsof -a -u www-data -i
Gerçek Senaryo 2: Şüpheli kullanıcı aktivitesi
Bir sistemde yetkisiz erişim şüphesi var. Hangi kullanıcının hangi dosyalara eriştiğini hızlıca görmek için:
# www-data kullanıcısının açtığı tüm dosyalar (web shell şüphesi)
sudo lsof -u www-data | grep -v "mem|txt|cwd|rtd"
# Aynı kullanıcının ağ bağlantıları
sudo lsof -a -u www-data -i TCP
# /tmp veya /var/tmp altındaki şüpheli açık dosyalar
sudo lsof | grep -E "/(tmp|var/tmp)/"
Dizin ve Dosya Bazlı Sorgular
Bir dosyanın veya dizinin kim tarafından kullanıldığını bulmak, özellikle umount işleminde “device is busy” hatasıyla karşılaştığınızda kritik önem taşır.
# Belirli bir dizindeki açık dosyaları bul (recursive değil)
sudo lsof +d /var/log/nginx/
# Recursive olarak dizin ağacındaki tüm açık dosyalar
sudo lsof +D /var/log/
# Belirli bir dosyayı kimin kullandığını öğren
sudo lsof /var/log/syslog
# Mount edilmiş bir dosya sistemini kimin kullandığını bul
sudo lsof +D /mnt/data/
Gerçek Senaryo 3: “Device or resource busy” hatası
NFS veya USB disk unmount etmeye çalışıyorsunuz ama sistem izin vermiyor:
# /mnt/usb üzerinde hangi süreçler çalışıyor?
sudo lsof +D /mnt/usb/
# Sadece PID'leri al ve fuser ile birlikte kullan
sudo lsof -t +D /mnt/usb/
# Alternatif olarak fuser
sudo fuser -m /mnt/usb/
# Tüm bu süreçleri sonlandır (dikkatli kullan!)
sudo lsof -t +D /mnt/usb/ | xargs kill -9
Silinmiş Ama Hâlâ Açık Dosyalar
Bu, Linux sysadmin’liğinin en sinsi disk alanı sorunlarından biridir. Bir log dosyasını sildiniz ama disk dolmaya devam ediyor. Çünkü o dosya hâlâ bir süreç tarafından açık tutuluyor ve inode serbest bırakılmıyor.
# Silinmiş ama hâlâ açık tutulan dosyaları bul
sudo lsof | grep deleted
# Daha odaklı arama
sudo lsof | grep -i "deleted" | awk '{print $1, $2, $7, $9}'
# Disk kaplayan silinmiş dosyaları boyuta göre sırala
sudo lsof | grep deleted | sort -k7 -rn | head -20
Gerçek Senaryo 4: Disk %95 dolu ama silinecek dosya yok
# Silinmiş ama açık tutulan büyük dosyaları tespit et
sudo lsof | grep deleted | awk '{print $7, $1, $2}' | sort -rn | head -10
# Örnek çıktı:
# 2147483648 java 4521 <- 2GB silinmiş log dosyası hâlâ Java sürecinde açık
# Çözüm 1: Süreci yeniden başlat
sudo systemctl restart uygulama-servisi
# Çözüm 2: Süreci kapatmadan dosyayı sıfırla (production'da tercih edilir)
# /proc/<PID>/fd/<FD> yolu üzerinden dosyayı truncate et
sudo truncate -s 0 /proc/4521/fd/5
Unix Domain Soketleri
Veritabanları, web sunucuları ve uygulama katmanları arasındaki iletişim sıklıkla Unix soketleri üzerinden olur. lsof bunları da izleyebilir:
# Unix domain soketlerini listele
sudo lsof -U
# MySQL soketini kimin kullandığını göster
sudo lsof /var/run/mysqld/mysqld.sock
# Docker unix soketini izle
sudo lsof /var/run/docker.sock
# Tüm unix soketleri ve bağlı süreçler
sudo lsof -a -U -u www-data
Gerçek Zamanlı İzleme ve Repeat Modu
lsof -r parametresi ile belirli aralıklarla yenilenen bir izleme kurabilirsiniz:
# Her 2 saniyede bir port 80'i izle
sudo lsof -i :80 -r 2
# Her 3 saniyede bir belirli sürecin bağlantılarını izle
sudo lsof -p 1234 -i -r 3 -n -P
# Çıktıyı log dosyasına yönlendir
sudo lsof -i TCP -s TCP:ESTABLISHED -r 5 -n -P >> /var/log/connections.log &
Script’lerde lsof Kullanımı
-t parametresi sadece PID döndürdüğü için shell script’lerde lsof çok pratik kullanılır:
#!/bin/bash
# Belirli bir portu dinleyen süreci güvenli şekilde sonlandır
PORT=8080
PID=$(sudo lsof -t -i :$PORT -s TCP:LISTEN)
if [ -z "$PID" ]; then
echo "Port $PORT üzerinde çalışan süreç bulunamadı."
else
echo "Port $PORT'u kullanan süreç PID: $PID"
echo "Süreç sonlandırılıyor..."
kill -TERM $PID
sleep 2
if kill -0 $PID 2>/dev/null; then
echo "Süreç hâlâ çalışıyor, SIGKILL gönderiliyor..."
kill -9 $PID
else
echo "Süreç başarıyla sonlandırıldı."
fi
fi
Performans İpuçları
lsof özellikle büyük sistemlerde yavaş çalışabilir. Performansı artırmak için:
# -n ile DNS çözümlemesini kapat (önemli hız farkı yaratır)
sudo lsof -i -n
# -P ile port isim çözümlemesini kapat
sudo lsof -i -n -P
# İkisini birleştir, production sistemlerde standart kullanım
sudo lsof -i TCP -n -P
# Çıktıyı önce dosyaya al, sonra analiz et
sudo lsof -n -P > /tmp/lsof_snapshot.txt
grep "LISTEN" /tmp/lsof_snapshot.txt
grep "ESTABLISHED" /tmp/lsof_snapshot.txt | wc -l
Güvenlik Denetimi Senaryosu
Bir sızma testi veya olay müdahalesi sırasında lsof çok değerli veriler sağlar:
# Sistemde ESTABLISHED durumundaki tüm dış bağlantılar
sudo lsof -i TCP -s TCP:ESTABLISHED -n -P | grep -v "127.0.0.1|::1"
# Alışılmadık portlarda dinleyen süreçler (1024 üstü)
sudo lsof -i TCP -s TCP:LISTEN -n -P | awk '$9 ~ /:([0-9]{4,})$/ {print}'
# Root olmayan bir kullanıcının açtığı ağ bağlantıları
sudo lsof -i -n -P | awk 'NR>1 && $3 != "root" {print}'
# /tmp veya home dışında çalışan şüpheli executable'lar
sudo lsof | grep " txt " | grep -E "(/tmp/|/dev/shm/)"
ss ve netstat ile Karşılaştırma
lsof -i ile ss veya netstat benzer bilgiler verse de aralarında farklar vardır. ss ve netstat ağ odaklıyken, lsof dosya tanıtıcısı merkezlidir. Hangi sürecin hangi soketi tuttuğunu öğrenmek için lsof daha doğrudan yanıt verir. Ancak hız açısından ss -tulnp çok daha hızlıdır. Birini diğerinin yerine koymak yerine birlikte kullanmak en doğru yaklaşımdır.
# ss ile hızlı port kontrolü
ss -tulnp | grep :80
# lsof ile o portu tutan süreçler hakkında daha fazla detay
sudo lsof -i :80 -n -P
# netstat hâlâ bazı sistemlerde tercih edilebilir
netstat -tulnp | grep :80
Pratik Bir Hızlı Başvuru Seti
Günlük kullanımda en sık başvurulan kombinasyonları bir arada görmek için şunu kullanabilirsiniz:
# Alias olarak .bashrc veya .zshrc'ye ekle
alias lsof-ports='sudo lsof -i -n -P -s TCP:LISTEN'
alias lsof-conn='sudo lsof -i -n -P -s TCP:ESTABLISHED'
alias lsof-deleted='sudo lsof | grep deleted'
alias lsof-net='sudo lsof -i -n -P'
Bu alias’ları tanımladıktan sonra lsof-ports yazarak dinleyen tüm portları, lsof-conn ile aktif bağlantıları anında görebilirsiniz.
Sonuç
lsof, Linux sistem yönetiminde gerçek anlamda İsviçre çakısı rolü üstlenen araçlardan biridir. Disk dolması problemlerinden güvenlik incelemelerine, port çakışmalarından süreç davranışı analizine kadar pek çok senaryoda vazgeçilmezdir. Öğrenme eğrisi başlangıçta biraz dik görünse de, temel filtreleme parametrelerini kavradıktan sonra lsof günlük rutin incelemelerinizin ayrılmaz bir parçası haline gelir.
En önemli nokta şudur: lsof çıktısını doğrudan yorumlamak yerine grep, awk, sort ve wc gibi araçlarla birleştirerek kullanmak hem odaklanmayı kolaylaştırır hem de otomasyon için zemin hazırlar. Script’lere -t parametresiyle PID çıktısı alarak entegre etmek, operasyonel iş akışlarını önemli ölçüde hızlandırır.
Sistemde bir şeyin garip davrandığını hissettiğinizde, sudo lsof -i -n -P ile başlamak çoğu zaman doğru iz bırakır. Gerisi zaten oradan açılır.