fuser Komutu ile Dosya ve Port Kullanan Süreçleri Tespit Etme ve Yönetme

Bir dosyayı silmeye çalışıyorsunuz, “device or resource busy” hatası alıyorsunuz. Bir portu dinlemeye başlamak istiyorsunuz, “address already in use” diyor. Bu anlar, sistem yöneticiliğinin en sinir bozucu dakikalarından biridir. İşte tam bu noktada fuser komutu devreye girer ve size “o dosyayı ya da o portu kim tutuyor?” sorusunun cevabını saniyeler içinde verir.

fuser aslında çoğu zaman lsof ya da netstat‘ın gölgesinde kalır. Oysa doğru ellerde son derece güçlü ve hızlı bir araçtır. Ben yıllardır üretim sunucularında hem dosya sistemi sorunlarını çözmek hem de port çakışmalarını tespit etmek için fuser‘ı aktif olarak kullanıyorum. Bu yazıda hem temel kullanımını hem de gerçek senaryolarda nasıl işe yaradığını aktaracağım.

fuser Nedir ve Nasıl Çalışır

fuser, “file user” kelimelerinin kısaltmasıdır. Temel amacı, belirtilen bir dosyayı, dizini veya soketi kullanan süreçlerin PID’lerini (Process ID) listelemektir. psmisc paketinin bir parçası olarak gelir ve neredeyse tüm Linux dağıtımlarında ya kurulu olarak bulunur ya da kolayca kurulabilir.

# Debian/Ubuntu tabanlı sistemlerde kurulum
sudo apt install psmisc

# RHEL/CentOS/AlmaLinux tabanlı sistemlerde
sudo dnf install psmisc

# Kurulu sürümü kontrol etmek için
fuser --version

Komutun mantığı şu şekilde işler: /proc dosya sistemi üzerinden her sürecin açık dosya tanımlayıcılarını (file descriptors) tarar ve belirtilen kaynakla eşleşenleri raporlar. Bu yüzden root yetkisi olmadan çalıştırdığınızda yalnızca kendi süreçlerinizi görebilirsiniz; tüm sistem genelinde tarama için sudo gerekir.

Temel Kullanım Sözdizimi

fuser [seçenekler] dosya_veya_port

En sık kullanılan parametreler şunlardır:

  • -v (–verbose): Ayrıntılı çıktı verir; kullanıcı adı, PID, erişim türü ve komut adını gösterir
  • -k (–kill): Tespit edilen süreçlere SIGKILL sinyali gönderir
  • -i (–interactive): -k ile birlikte kullanılır, her öldürme işlemi öncesi onay ister
  • -n (–namespace): Alan adı belirtir; tcp, udp veya file olabilir
  • -l (–list-signals): Kullanılabilecek sinyal listesini gösterir
  • -s (–silent): Sessiz mod; sadece PID’leri döndürür, hata mesajı göstermez
  • -u (–user): Çıktıya kullanıcı adını ekler
  • -m (–mount): Belirtilen dosya sistemi veya blok cihazını kullanan tüm süreçleri listeler
  • -a (–all): Erişim yoksa da tüm dosyaları listeler
  • -4: Yalnızca IPv4 adreslerini tarar
  • -6: Yalnızca IPv6 adreslerini tarar

Dosya Kullanan Süreçleri Tespit Etmek

En basit kullanım senaryosundan başlayalım. Bir log dosyasının hangi süreç tarafından açık tutulduğunu öğrenmek istiyorsunuz:

# Temel kullanım - sadece PID'leri döndürür
fuser /var/log/nginx/access.log

# Ayrıntılı çıktı için -v parametresi
fuser -v /var/log/nginx/access.log

-v parametresiyle aldığınız çıktı şöyle görünür:

                     USER        PID ACCESS COMMAND
/var/log/nginx/access.log:
                     root       1423 F.... nginx
                     www-data   1424 F.... nginx

Buradaki ACCESS sütunu önemlidir. Bu sütundaki harflerin anlamları:

  • c: Sürecin mevcut çalışma dizini (current directory)
  • e: Çalıştırılabilir dosya olarak kullanılıyor
  • f: Dosya açık (normal okuma/yazma)
  • F: Dosya yazma için açık
  • r: Root dizin olarak kullanılıyor
  • m: Belleğe eşlenmiş dosya ya da paylaşılan kütüphane

Port Kullanan Süreçleri Tespit Etmek

fuser‘ın belki de en kullanışlı özelliği ağ portlarını izlemesidir. Sözdizimi biraz farklıdır: port numarasının yanına protokolü de belirtmeniz gerekir.

# 80 numaralı TCP portunu kullanan süreci bul
sudo fuser 80/tcp

# 443 numaralı HTTPS portunu ayrıntılı göster
sudo fuser -v 443/tcp

# 53 numaralı UDP portunu kontrol et (DNS)
sudo fuser -v 53/udp

# Birden fazla portu aynı anda sorgula
sudo fuser -v 80/tcp 443/tcp 8080/tcp

Bir web sunucusu kurarken 8080 portunda zaten bir şeyler çalışıyorsa ve bunu bulmak istiyorsanız:

sudo fuser -v -n tcp 8080

Bu komut size hem PID’i hem de o PID’e ait komutu gösterecektir. Oradan doğrudan kill komutuna geçebilir ya da süreci tanımlayıp neden çalıştığını anlayabilirsiniz.

Gerçek Dünya Senaryosu 1: “Port Already in Use” Sorunu

Geçen ay bir uygulama dağıtımı sırasında tam olarak bu sorunla karşılaştım. Yeni bir Java uygulamasını 8443 portunda ayağa kaldırmaya çalışıyorduk ve şu hatayı aldık:

java.net.BindException: Address already in use (Bind failed)

Klasik refleks netstat -tulpn | grep 8443 yazmak olurdu ama fuser çok daha hızlı sonuç verdi:

sudo fuser -v 8443/tcp

Çıktı bize eski bir test deployment’ından kalma bir Java process’in hâlâ o portu tuttuğunu gösterdi. PID’i öğrendikten sonra:

# Süreci tanımlamak için
ps aux | grep 3471

# Ya da daha temiz görünüm için
ps -p 3471 -o pid,ppid,cmd,user,lstart

# Süreci sonlandırmak için
sudo kill -15 3471

# Eğer SIGTERM işe yaramazsa
sudo kill -9 3471

Burada önemli bir not: Üretim ortamında körü körüne kill -9 atmadan önce ne çalıştığını anladığınızdan emin olun. fuser size PID’i verir, ama o PID’in neden orada olduğunu anlamak sizin işiniz.

Gerçek Dünya Senaryosu 2: “Device is Busy” ve Bağlı Dosya Sistemi

NFS ya da yerel bağlı (mounted) bir dosya sistemini umount etmeye çalışırken “device is busy” hatası almak son derece yaygın bir durumdur. fuser -m burada inanılmaz işe yarar:

# Bir mount noktasını kullanan tüm süreçleri listele
sudo fuser -v -m /mnt/data

# Ya da blok cihazını doğrudan belirt
sudo fuser -v -m /dev/sdb1

Bu komut, /mnt/data altındaki herhangi bir dosyayı açık tutan, o dizinde çalışan ya da o dosya sisteminden bir şey çalıştıran tüm süreçleri listeler. Sonuçta genellikle birinin terminal oturumunu o dizinde açık bıraktığını ya da bir log rotation scriptinin henüz tamamlanmadığını görürsünüz.

# Tespit ettikten sonra güvenli bir şekilde sonlandırıp unmount etmek
sudo fuser -k -m /mnt/data
sudo umount /mnt/data

Ama dikkatli olun: -k parametresi tespit ettiği tüm süreçlere SIGKILL gönderir. Üretimde bunu yapmadan önce hangi süreçlerin etkileneceğini -v ile görün.

Gerçek Dünya Senaryosu 3: Silinemeyen Dosya Sorunları

Bir konfigürasyon dosyasını güncellemek için önce eskisini silmeye çalışıyorsunuz ama silemiyor ya da üzerine yazamıyorsunuz. Bu durumda:

# Dosyayı kimin kullandığını öğren
sudo fuser -v /etc/app/config.yml

# Kullanıcı bilgisiyle birlikte göster
sudo fuser -u /etc/app/config.yml

Eğer çıktı boşsa dosyayı kimse kullanmıyor demektir; sorun izinlerden ya da chattr ile kilitlenmişlikten kaynaklanıyor olabilir. Ama çıktıda bir PID görüyorsanız, o süreci durdurmadan dosyayı değiştirmeniz riskli olabilir.

-k Parametresi: Dikkatli Kullanın

fuser -k güçlü ama tehlikeli bir kombinasyondur. Doğrudan belirtilen kaynağı kullanan tüm süreçlere SIGKILL gönderir. Bunu biraz daha güvenli kullanmak için -i parametresini ekleyin:

# Her öldürme işleminden önce onay iste
sudo fuser -k -i /var/log/uygulama.log

# Belirli bir sinyal göndermek isterseniz
sudo fuser -k -TERM 80/tcp

# Kullanılabilecek sinyalleri listele
fuser -l

SIGKILL yerine önce SIGTERM göndermek her zaman daha iyi bir pratiktir. Uygulamaya kendini düzgünce kapatma fırsatı tanırsınız:

# Önce nazik bir şekilde durdurmayı dene
sudo fuser -k -TERM 9200/tcp

# Birkaç saniye bekle
sleep 5

# Hâlâ çalışıyorsa sert önlem al
sudo fuser -k -KILL 9200/tcp

Birden Fazla Kaynağı Aynı Anda Sorgulamak

fuser birden fazla kaynak için aynı anda çalışabilir. Bu özellik monitoring scriptleri yazarken çok işe yarar:

# Birden fazla dosyayı sorgula
sudo fuser -v /var/log/syslog /var/log/auth.log /tmp/lock.file

# Birden fazla portu kontrol et
sudo fuser -v 80/tcp 443/tcp 8080/tcp 3000/tcp

# Karışık sorgular da mümkündür
sudo fuser -v /etc/nginx/nginx.conf 80/tcp 443/tcp

Bash Scriptleri ile fuser Kullanımı

fuser‘ın çıktısını script içinde kullanmak istediğinizde -s (silent) modu çok işe yarar. Eğer belirtilen kaynağı kullanan bir süreç varsa çıkış kodu 0, yoksa 1 döndürür:

#!/bin/bash
# Port kontrol scripti

PORT=8080
PROTOCOL=tcp

if sudo fuser -s ${PORT}/${PROTOCOL} 2>/dev/null; then
    echo "Uyari: ${PORT}/${PROTOCOL} portu kullanımda!"
    echo "Kullanan süreçler:"
    sudo fuser -v ${PORT}/${PROTOCOL}
    
    read -p "Bu süreçleri sonlandırmak istiyor musunuz? (e/h): " yanit
    if [[ "$yanit" == "e" ]]; then
        sudo fuser -k -TERM ${PORT}/${PROTOCOL}
        echo "SIGTERM gönderildi."
    fi
else
    echo "Port ${PORT}/${PROTOCOL} müsait."
fi

Bir başka örnek: Deployment öncesi port müsaitliğini kontrol eden bir script:

#!/bin/bash
# deployment-check.sh
# Uygulama başlatılmadan önce gerekli portların müsait olup olmadığını kontrol eder

GEREKLI_PORTLAR=(8080 8443 9090)
HATA=0

for port in "${GEREKLI_PORTLAR[@]}"; do
    if sudo fuser -s ${port}/tcp 2>/dev/null; then
        echo "[HATA] Port ${port}/tcp zaten kullanımda:"
        sudo fuser -v ${port}/tcp 2>&1
        HATA=1
    else
        echo "[OK] Port ${port}/tcp müsait."
    fi
done

if [[ $HATA -eq 1 ]]; then
    echo ""
    echo "Deployment başlatılamıyor. Lütfen yukarıdaki çakışmaları çözün."
    exit 1
fi

echo ""
echo "Tüm portlar müsait. Deployment başlıyor..."
exit 0

fuser vs lsof vs ss: Hangisini Ne Zaman Kullanmalı

Bu araçların birbirinin alternatifi olmaktan çok birbirini tamamladığını düşünüyorum.

  • fuser: Tek bir dosya veya port için hızlı yanıt istediğinizde, özellikle script içinde exit code’a ihtiyaç duyduğunuzda ideal
  • lsof: Bir sürecin tüm açık dosyalarını görmek istediğinizde, daha karmaşık filtreleme senaryolarında güçlü
  • ss (ya da eski netstat): Genel ağ durumuna bakmak, bağlantı listelerini incelemek için daha uygun

Pratik bir karşılaştırma:

# "8080 portunu kim tutuyor?" sorusu için üç yöntem

# fuser ile (en hızlı, en özlü)
sudo fuser -v 8080/tcp

# lsof ile (daha detaylı bilgi)
sudo lsof -i :8080

# ss ile
sudo ss -tlnp | grep :8080

Günlük işlerimde genellikle önce fuser ile hızlıca bir baktım, daha derin inceleme gerekiyorsa lsof‘a geçtim.

IPv4 ve IPv6 Ayrımı

Bir portu kontrol ederken sadece IPv4 ya da IPv6 üzerinde dinleyen süreçleri filtrelemek isteyebilirsiniz:

# Sadece IPv4 üzerinde 80 portunu kontrol et
sudo fuser -4 -v 80/tcp

# Sadece IPv6 üzerinde 80 portunu kontrol et
sudo fuser -6 -v 80/tcp

# Her ikisini de göster (varsayılan davranış)
sudo fuser -v 80/tcp

Bu özellik çift-yığın (dual-stack) yapılandırılmış sistemlerde oldukça kullanışlıdır. Özellikle “sadece IPv6’da dinliyorum ama IPv4 bağlantısı gelmiyor neden?” tipindeki sorunları debug ederken işe yarar.

Güvenlik Açısından fuser

fuser‘ın bir güvenlik implicasyonu var: Normal kullanıcılar yalnızca kendi süreçlerine ait bilgileri görebilir. Bu bir özellik aslında. Ama şunu belirtmek gerek: Eğer bir sistemde kimin ne tuttuğunu görmek istiyorsanız mutlaka sudo ile çalıştırın, aksi halde eksik sonuç alırsınız ve bu yanıltıcı olabilir.

# Root olmadan çalıştırırsanız (sadece kendi süreçleriniz görünür)
fuser -v 80/tcp

# Root ile çalıştırırsanız (tüm süreçler görünür)
sudo fuser -v 80/tcp

Özellikle “port kullanılmıyor, müsait” gibi bir sonuç aldığınızda ve bir şeylerin yanlış olduğunu hissediyorsanız, sudo olmadan çalıştırmış olma ihtimalinizi kontrol edin.

Sonuç

fuser, basit görünen ama doğru anda hayat kurtaran bir araçtır. “Dosya meşgul” ve “port kullanımda” hatalarıyla boğuşurken uzun lsof çıktılarını filtrelemek yerine, hedefli ve hızlı bir çözüm sunar. Özellikle şu senaryolarda vazgeçilmez olduğunu defalarca deneyimledim:

  • Deployment öncesi port çakışması kontrolü
  • “Busy” hatası veren dosya sistemlerini unmount etmeden önce
  • Lock dosyalarını tutan hayalet süreçleri bulmak
  • Otomatik remediation scriptlerinde exit code kontrolü

Tek bir öneri ile bitireyim: fuser -k kullanmadan önce mutlaka fuser -v ile ne öldüreceğinizi görün. Üretim ortamında kör ateş etmek, sorunu çözmekten daha büyük bir soruna yol açabilir. Önce tanımla, sonra müdahale et. Bu, sistem yöneticiliğinin değişmeyen altın kurallarından biridir.

Bir yanıt yazın

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