Sistem yönetiminde zamanla biriken “hayalet” dosyalar arasında en sinir bozucu olanlarından biri şüphesiz bozuk sembolik linklerdir. Bir paketi kaldırdınız, bir dizini taşıdınız ya da bir uygulama güncellemesi sırasında bir şeyler ters gitti ve geride hedefi olmayan sembolik linkler kaldı. Bu linkler disk alanı açısından neredeyse hiç yer kaplamaz ama production ortamında ciddi sorunlara yol açabilir: script’ler çalışmaz, servisler başlamaz, derleme süreçleri patlayabilir. Bu yazıda bozuk sembolik linkleri nasıl bulacağınızı, nasıl analiz edeceğinizi ve güvenli bir şekilde nasıl temizleyeceğinizi ele alacağız.
Sembolik Link Nedir, Neden Bozulur?
Sembolik link (symlink), bir dosya veya dizine işaret eden bir kısayol gibi düşünebilirsiniz. Asıl dosyanın kendisi değil, ona giden bir yol referansı içerir. Linux sistemlerde son derece yaygın kullanılır: /usr/bin/python aslında python3.11‘e işaret eden bir symlink olabilir, /etc/alternatives/ dizini de benzer şekilde çalışır.
Bozuk (dangling/broken) sembolik link ise hedefi artık mevcut olmayan bir linktir. Bunun başlıca nedenleri şunlardır:
- Hedef dosya veya dizin silindi
- Hedef dosya başka bir konuma taşındı
- Hedef paketi kaldırıldı (örneğin
apt removesonrası) - Göreceli path ile oluşturulmuş link, sonradan dizin yapısı değiştiğinde bozuldu
- NFS mount’ları veya harici diskler bağlantısı kesildiğinde geride kalan linkler
# Basit bir örnek: bozuk symlink nasıl oluşur?
echo "test" > /tmp/asil_dosya.txt
ln -s /tmp/asil_dosya.txt /tmp/link_dosya
ls -la /tmp/link_dosya
# lrwxrwxrwx 1 root root 20 Ara 5 10:00 /tmp/link_dosya -> /tmp/asil_dosya.txt
rm /tmp/asil_dosya.txt
ls -la /tmp/link_dosya
# Hala görünür ama rengi kırmızıya döner (ls renk desteğiyle)
cat /tmp/link_dosya
# cat: /tmp/link_dosya: No such file or directory
Yukarıdaki örnekte link hala dosya sisteminde var ama artık işe yaramaz bir referans. İşte bulmamız gereken tam olarak bu tür linkler.
find Komutu ile Bozuk Linkleri Tespit Etme
find komutu bu iş için en güçlü aracımız. -type l parametresi symlink’leri, ! -e ise hedefi olmayan (erişilemeyen) linkleri filtreler.
# Belirli bir dizinde bozuk symlink'leri bul
find /usr/local -type l ! -exec test -e {} ; -print
# Daha okunabilir alternatif
find /home -xtype l
# /xtype l: sembolik linkin hedefini takip ederek kontrol eder
# Hedef yoksa bu link listelenir
Burada -xtype l parametresi özellikle önemli. Normal -type l her sembolik linki listeler, -xtype l ise yalnızca hedefi olmayan veya erişilemeyen symlink’leri döner. Bu ikinci yöntem çok daha temiz sonuç verir.
# Sistem genelinde tarama (root olarak)
find / -xtype l 2>/dev/null
# Bazı dizinleri hariç tutarak (proc ve sys gereksiz yere işleme alınmasın)
find / -xtype l
-not -path "/proc/*"
-not -path "/sys/*"
-not -path "/run/*"
2>/dev/null
# Sadece belirli bir kullanıcının home dizinini tara
find /home/ahmet -xtype l 2>/dev/null
2>/dev/null kısmını atlamayın, yoksa “Permission denied” mesajları çıktıyı berbat eder.
Bozuk Linkleri Detaylı İnceleme
Bir linki buldunuz, şimdi ne yapacaksınız? Silmeden önce ne olduğunu anlamak için birkaç komut kullanın:
# Linkin nereye işaret ettiğini gör
ls -la /usr/bin/python
# readlink ile hedef yolu oku
readlink /usr/bin/python
readlink -f /usr/bin/python # -f: tüm zinciri çözer (canonical path)
# file komutu da faydalı bilgi verir
file /usr/bin/python
# /usr/bin/python: broken symbolic link to /usr/bin/python3.8
Büyük bir liste ile karşılaştığınızda her birinin hedefini görmek için şöyle bir şey yazabilirsiniz:
# Her bozuk linkin hedefini göster
find /usr -xtype l 2>/dev/null | while read link; do
echo "BOZUK LINK: $link"
echo " -> Hedef: $(readlink $link)"
echo "---"
done
Bu çıktıya bakarak hangi paket kaldırıldığında bu linkler oluştu, hangi dizin yapısı değişti gibi soruların cevabını çoğu zaman anlayabilirsiniz.
Gerçek Dünya Senaryosu: Node.js Güncellemesi Sonrası
Diyelim ki nvm veya doğrudan paket yöneticisi ile Node.js’i güncellediniz ve ardından bazı global paketlerin binary’leri çalışmaz hale geldi. Bu çok yaygın bir durum.
# npm global binary'lerinin bulunduğu dizini kontrol et
find /usr/local/bin -xtype l 2>/dev/null
# Çıktı:
# /usr/local/bin/gulp
# /usr/local/bin/webpack
# /usr/local/bin/pm2
# Bu linkler nereye işaret ediyor?
for link in $(find /usr/local/bin -xtype l 2>/dev/null); do
echo "$link -> $(readlink $link)"
done
# /usr/local/bin/gulp -> ../lib/node_modules/gulp/bin/gulp.js
# /usr/local/bin/webpack -> ../lib/node_modules/webpack-cli/bin/cli.js
# /usr/local/bin/pm2 -> ../lib/node_modules/pm2/bin/pm2
Görüyorsunuz, hedef modüller artık mevcut değil. Node.js sürümü değişti, modüller farklı bir path’e taşındı ya da silinmesi gereken bir şey temizlendi. Bu durumda bozuk linkleri temizleyip paketleri yeniden yüklemek gerekir.
symlinks Aracı: Özel Amaçlı Çözüm
find her ne kadar güçlü olsa da symlinks adında bu iş için özel geliştirilmiş bir araç var. Çoğu dağıtımda paket depolarında mevcut.
# Kurulum
sudo apt install symlinks # Debian/Ubuntu
sudo dnf install symlinks # Fedora/RHEL
sudo pacman -S symlinks # Arch Linux
# Temel kullanım
symlinks /usr/local
# Bozuk linkleri verbose modda listele
symlinks -v /home
# Alt dizinlere de in (recursive)
symlinks -r /usr/local
# Çıktı anlamları:
# dangling: hedefi olmayan (bozuk) linkler
# relative: göreceli path kullanan linkler
# absolute: mutlak path kullanan linkler
# lengthy: gereksiz uzun path içeren linkler
# messy: ../.. gibi karmaşık relative path içerenler
# other_fs: farklı dosya sistemine işaret edenler
symlinks çıktısı çok daha organize ve anlaşılır. Her linki kategorize eder. Bozuk olanlar “dangling” olarak işaretlenir.
# Sadece bozuk linkleri göster ve sil (dikkatli!)
symlinks -rd /usr/local
# -r: recursive
# -d: dangling (bozuk) olanları sil
Dikkat: -d parametresini doğrudan kullanmadan önce -r ile listeyi gözden geçirin. Üretim sunucusunda silme işlemini kör kör yapmayın.
Bozuk Linkleri Güvenli Şekilde Temizleme
Temizlik yaparken en büyük risk yanlış bir şeyi silmek. Bu yüzden şu adımları takip edin:
1. Adım: Önce listele, not al
# Temizlik yapacağınız dizinde bozuk linkleri dosyaya kaydet
find /opt -xtype l 2>/dev/null > /tmp/bozuk_linkler.txt
cat /tmp/bozuk_linkler.txt
wc -l /tmp/bozuk_linkler.txt # Kaç tane var?
2. Adım: Her birini gözden geçir
# Listeden tek tek geç ve hedeflerine bak
while IFS= read -r link; do
target=$(readlink "$link")
echo "Link: $link"
echo "Hedef: $target"
echo "Hedef mevcut mu: $(test -e "$target" && echo 'EVET' || echo 'HAYIR')"
echo "---"
done < /tmp/bozuk_linkler.txt
3. Adım: Kritik değilse sil
# Güvenli silme: dosyayı okuyarak tek tek sil
while IFS= read -r link; do
echo "Siliniyor: $link"
rm "$link"
done < /tmp/bozuk_linkler.txt
# Veya xargs ile (çok sayıda dosya için daha hızlı)
xargs rm < /tmp/bozuk_linkler.txt
4. Adım: find ile doğrudan sil (tek satır)
# Bulduğunda direkt sil - ÇOK DİKKATLİ KULLANIN
find /opt -xtype l -delete
# Daha güvenli: önce -print ile gör, sonra -delete ekle
find /opt -xtype l -print
find /opt -xtype l -print -delete # Her silinen öğeyi yazdırır
-delete parametresi -print‘ten önce veya sonra yazılabilir ama her zaman önce -print ile test etmenizi öneririm.
Sistem Geneli Temizlik Senaryosu
Büyük bir sunucu temizliği yapıyorsanız ya da uzun süredir güncellenmemiş bir sistemi düzene sokuyorsanız daha kapsamlı bir yaklaşım gerekir:
#!/bin/bash
# bozuk_link_temizlik.sh
LOG_FILE="/var/log/symlink_temizlik_$(date +%Y%m%d_%H%M%S).log"
TARANACAK_DIZINLER="/usr /opt /home /var/www"
echo "Bozuk symlink taraması başlıyor: $(date)" | tee "$LOG_FILE"
echo "========================================" | tee -a "$LOG_FILE"
TOPLAM=0
for dizin in $TARANACAK_DIZINLER; do
if [ -d "$dizin" ]; then
echo "" | tee -a "$LOG_FILE"
echo "Dizin taranıyor: $dizin" | tee -a "$LOG_FILE"
BULUNAN=$(find "$dizin" -xtype l 2>/dev/null)
SAYI=$(echo "$BULUNAN" | grep -c . 2>/dev/null || echo 0)
if [ "$SAYI" -gt 0 ]; then
echo " Bulunan bozuk link sayısı: $SAYI" | tee -a "$LOG_FILE"
echo "$BULUNAN" | while read link; do
echo " [BOZUK] $link -> $(readlink $link)" | tee -a "$LOG_FILE"
done
TOPLAM=$((TOPLAM + SAYI))
else
echo " Temiz, bozuk link yok." | tee -a "$LOG_FILE"
fi
fi
done
echo "" | tee -a "$LOG_FILE"
echo "Toplam bozuk link: $TOPLAM" | tee -a "$LOG_FILE"
echo "Log dosyası: $LOG_FILE"
echo ""
echo "Temizlik yapmak için şunu çalıştırın:"
echo " grep '[BOZUK]' $LOG_FILE | awk '{print $2}' | xargs rm"
Bu script önce sadece raporlar, silmez. Log dosyasına bakıp emin olduktan sonra alt kısımdaki komutu çalıştırırsınız.
/etc/alternatives Dizini: Özel Durum
Debian/Ubuntu sistemlerde /etc/alternatives dizini tamamen symlink’lerden oluşur ve update-alternatives sistemi tarafından yönetilir. Bu dizinde bozuk link bulursanız dikkatli olun, doğrudan silmek yerine update-alternatives ile düzeltmek daha doğru yaklaşımdır.
# Tüm alternatives durumunu gör
update-alternatives --get-selections
# Bozuk bir alternatifi düzelt
# Örneğin java bozulduysa
update-alternatives --config java
# Veya otomatik moda al
update-alternatives --auto java
# /etc/alternatives içindeki bozuk linkleri kontrol et
find /etc/alternatives -xtype l 2>/dev/null
Eğer update-alternatives ile çözemediğiniz bozuk bir link varsa, ilgili paketi yeniden yüklemek genellikle en temiz çözümdür:
sudo apt install --reinstall <paket-adi>
Otomatik Temizlik için Cron Job
Düzenli olarak bakım yapılan bir sistem için haftalık otomatik tarama işe yarar. Silme işlemini otomatize etmek riskli olduğundan sadece raporlama yapan bir cron job öneririm:
# /etc/cron.weekly/symlink_check dosyası oluştur
cat > /etc/cron.weekly/symlink_check << 'EOF'
#!/bin/bash
RAPOR="/var/log/bozuk_symlink_raporu.txt"
TARIH=$(date '+%Y-%m-%d %H:%M:%S')
echo "[$TARIH] Bozuk symlink taraması" > "$RAPOR"
find /usr /opt /home /var/www -xtype l 2>/dev/null >> "$RAPOR"
SAYI=$(grep -c . "$RAPOR" 2>/dev/null)
SAYI=$((SAYI - 1)) # Başlık satırını çıkar
if [ "$SAYI" -gt 0 ]; then
echo "UYARI: $SAYI adet bozuk symlink bulundu. Detaylar: $RAPOR" |
mail -s "Bozuk Symlink Uyarısı - $(hostname)" root
fi
EOF
chmod +x /etc/cron.weekly/symlink_check
Bu sayede her hafta sisteminizde bozuk link birikip birikmediğini takip edebilirsiniz.
Bozuk Linkleri Onarmak: Silmek Tek Seçenek Değil
Bazen bozuk bir linki silmek yerine onarmak daha mantıklıdır. Özellikle bir uygulama veya konfigürasyon o linke bağımlıysa.
# Linkin mevcut hedefini gör
readlink /usr/bin/python
# Çıktı: /usr/bin/python3.8 (artık mevcut değil)
# Mevcut python3 sürümünü bul
ls /usr/bin/python*
# /usr/bin/python3 /usr/bin/python3.10
# Linki güncelle (sil ve yeniden oluştur)
ln -sf /usr/bin/python3.10 /usr/bin/python
# -s: symbolic
# -f: force (varsa üstüne yaz)
# Doğrula
ls -la /usr/bin/python
python --version
Toplu onarım senaryosu için, diyelim ki Node.js sürüm değişikliğinden kaynaklanan bir durumu düzeltiyorsunuz:
# Eski sürüme işaret eden linkleri yeni sürüme yönlendir
OLD_PATH="/usr/local/lib/node_modules"
NEW_PATH="/usr/lib/node_modules"
find /usr/local/bin -xtype l 2>/dev/null | while read link; do
old_target=$(readlink "$link")
new_target="${old_target/$OLD_PATH/$NEW_PATH}"
if [ -e "$new_target" ]; then
echo "Onarılıyor: $link -> $new_target"
ln -sf "$new_target" "$link"
else
echo "Onarılamaz (yeni hedef de yok): $link"
fi
done
Sık Yapılan Hatalar
Hata 1: Sistem dizinlerini dikkatsizce temizlemek
/lib, /lib64, /usr/lib gibi dizinlerde bozuk symlink bulduğunuzda doğrudan silmeyin. Bu linkler çoğu zaman bir paketin eksik kurulumu veya bozulmuş bir güncelleme sonucu oluşur. Doğru çözüm:
# Hangi pakete ait olduğunu bul
dpkg -S /lib/x86_64-linux-gnu/libcorrupt.so.1
# O paketi yeniden yükle
sudo apt install --reinstall libpaket-dev
Hata 2: find yerine ls kullanmak
ls -la ile sembolik linkler görünür ama bozuk olup olmadıklarını toplu kontrol etmek için find -xtype l çok daha verimli.
Hata 3: /proc ve /sys dizinlerini taramak
Bu sanal dosya sistemleri gerçek dosya içermez ve burada “bozuk link” olarak görünen şeyler aslında normaldir. Her zaman bu dizinleri dışarıda bırakın.
find / -xtype l
-not -path "/proc/*"
-not -path "/sys/*"
-not -path "/run/*"
-not -path "/dev/*"
2>/dev/null
Sonuç
Bozuk sembolik linkleri yönetmek aslında basit ama göz ardı edildiğinde can sıkıcı sorunlara kapı aralayan bir bakım görevidir. Özetlemek gerekirse:
- Tespit için
find / -xtype lveyasymlinks -r /dizinkullanın - Analiz için
readlink,ls -lavefilekomutlarından yararlanın - Temizlik öncesinde mutlaka listeyi gözden geçirin ve bir log dosyasına alın
- Sistem dizinlerinde silmek yerine
--reinstallile paketi onarın - Düzenli kontrol için haftalık bir cron job kurun
Production sistemlerde “önce anla, sonra sil” prensibi hayat kurtarır. find -xtype l -delete tek satırda her şeyi çözer ama yanlış dizinde çalıştırılırsa işler karışabilir. Biraz fazla dikkat hiçbir zaman zarar vermez.