Kafayı yiyecektim arkadaşlar. Şaka gibi ama, hafta sonu oturup güzel bir arşivleme botu yazdım. Python'la, os.walk ile belirlediğim klasördeki her şeyi dolaşıp, shutil.make_archive ile güzelce ZIP'liyordu. Her şey mükemmel çalışıyordu, ta ki test klasörümdeki o symbolic link'i görene kadar.
Linklerin İhaneti ve Patlayan ZIP
Bot, gayet "çalışkan" bir şekilde, bir dizine verdiğim sembolik linki takip etti ve linkin gösterdiği yerdeki TÜM dosyaları, hatta sistemin kritik /usr/bin gibi yerlerindeki dosyaları bile, hiç tereddüt etmeden arşivime kopyalamaya başladı. Ortaya çıkan ZIP dosyasının boyutunu görünce yüreğim ağzıma geldi. "Bu kadar dosya nereden çıktı ya?" diye dakikalarca baktım koda.
Çözüm: os.path.islink() Kurtarıcım Oldu
StackOverflow'da bile doğrudan bu sorunu arayıp bulamadım. Meğerse sorun şuradaymış: os.walk, varsayılan olarak symbolic link'leri takip etmiyor ama, followlinks=True parametresi verirseniz veya link olan bir şeyin hedefini okumaya çalışırsanız, o zaman işler karışıyor. Benim botum da dosya yolunu alıp doğrudan ekleme mantığıyla çalıştığı için linkin kendisi yerine, işaret ettiği yerdeki her şeyi alıyordu.
Çözüm basitti aslında. Her dosya yolunu eklemeden önce, bunun bir sembolik link olup olmadığını kontrol etmek:
Böylece bot, sadece gerçek dosyaları alıp, linkleri görmezden gelmeye başladı. İsterseniz linkin kendisini de (hedefini değil) arşive ekleyebilirsiniz, ama benim ihtiyacım o değildi.
Alınan Ders: Walk Dikkatli Kullanılmalı
os.walk güçlü bir araç ama, özellikle sistem dosyaları veya izinlerle uğraşıyorsanız, her adımda neyi işlediğinize dikkat etmeniz gerekiyor. Bir de, otomasyon script'lerinizi asla root yetkisiyle veya sistemin kritik dizinlerini hedef göstererek test etmeyin. Neredeyse kendi işletim sistemimin yedeğini alıyordum!
Siz de benzer bir otomasyonda böyle sürprizlerle karşılaştınız mı? Ya da shutil kütüphanesinde symbolic link'ler için daha temiz bir yöntem biliyor musunuz? Yorumlara yazın, konuşalım!
Bot, gayet "çalışkan" bir şekilde, bir dizine verdiğim sembolik linki takip etti ve linkin gösterdiği yerdeki TÜM dosyaları, hatta sistemin kritik /usr/bin gibi yerlerindeki dosyaları bile, hiç tereddüt etmeden arşivime kopyalamaya başladı. Ortaya çıkan ZIP dosyasının boyutunu görünce yüreğim ağzıma geldi. "Bu kadar dosya nereden çıktı ya?" diye dakikalarca baktım koda.
Python:
for root, dirs, files in os.walk(source_dir):
for file in files:
file_path = os.path.join(root, file)
# Meğerse burada symbolic link kontrolü YOKTU!
StackOverflow'da bile doğrudan bu sorunu arayıp bulamadım. Meğerse sorun şuradaymış: os.walk, varsayılan olarak symbolic link'leri takip etmiyor ama, followlinks=True parametresi verirseniz veya link olan bir şeyin hedefini okumaya çalışırsanız, o zaman işler karışıyor. Benim botum da dosya yolunu alıp doğrudan ekleme mantığıyla çalıştığı için linkin kendisi yerine, işaret ettiği yerdeki her şeyi alıyordu.
Çözüm basitti aslında. Her dosya yolunu eklemeden önce, bunun bir sembolik link olup olmadığını kontrol etmek:
Python:
if not os.path.islink(file_path):
# Güvenle ZIP'e ekle
pass
else:
print(f"[UYARI] Symbolic link atlandı: {file_path}")
Böylece bot, sadece gerçek dosyaları alıp, linkleri görmezden gelmeye başladı. İsterseniz linkin kendisini de (hedefini değil) arşive ekleyebilirsiniz, ama benim ihtiyacım o değildi.
os.walk güçlü bir araç ama, özellikle sistem dosyaları veya izinlerle uğraşıyorsanız, her adımda neyi işlediğinize dikkat etmeniz gerekiyor. Bir de, otomasyon script'lerinizi asla root yetkisiyle veya sistemin kritik dizinlerini hedef göstererek test etmeyin. Neredeyse kendi işletim sistemimin yedeğini alıyordum!
Siz de benzer bir otomasyonda böyle sürprizlerle karşılaştınız mı? Ya da shutil kütüphanesinde symbolic link'ler için daha temiz bir yöntem biliyor musunuz? Yorumlara yazın, konuşalım!