• Linux Sistem Yönetimi | LKD #4

    Paket Yönetimi

    Paket yöneticileri, bir paketi indirmemize, kurmamıza, kaldırmamıza, bağımlılıkları yönetmemize ve sistemimizde halihazırda var olan paketleri güncellememize yarar. Farklı dağıtımlar farklı paket yöneticileri kullanabilirler, dağıtımlar arasında en çok fark da bu konu da yaşanır, örneğin:

    • Debian apt’yi,
    • Rocky linux dnf’i,
    • Arch Linux pacman’i paket yöneticisi olarak kullanır.

    Linux’ta bir paket kurduğumuzda, paketin çalışabilmesi için ihtiyaç duyduğu bağımlılıklar da beraberinde kurulur. Hangi bağımlılıkların gerekli olduğunu tespit eden ve bunların kurulumunu yöneten araçlar ise paket yöneticileridir.

    Kurduğumuz programların hangi kütüphanelere bağımlı olduğunu anlamak için, öncelikle which ile çalıştırılabilir dosyasının nerede olduğunu bulup ldd komutuyla bağımlılıklarını tespit ederiz.

    bash
    mehmet@debian ~$ ldd /usr/bin/nano

    komutunu girdiğimizde çıktısı,

    şeklinde olur. Burada nano’nun çalışması için gerekli olan kütüphaneler listelenmiştir. Sol tarafta nano’nun istediği ana kütüphaneler, sağ taraftaysa onların nerede bulunduğu yazıyor.

    Not: İllaki indirdiğimiz dosyanın bağımlılıkları burada görünür diye bir kural yoktur, bağımlılıkları statik olarak programın içine gömersek ldd çıktısında görünmezler.

    Paket yöneticileri bir paketi güncellerken depo indeksi numarasına bakarak yaparlar, yereldeki indeks numarası depodaki indeks numarasından daha eskiyse bunu güncellerler. (.deb paketini apt ile indirip versiyonunu düşürdüğümde paket yöneticisi versiyonun güncel olmadığını sanıp paketi güncelledi) .

    Debian’da versiyon numaralarını kontrol etmek için sudo apt update komutu çalıştırılır. Rocky’de bu iş dnf update ile tek komutta çözülür.

    Büyük sunucu sistemlerini düşündüğümüzde bir paket güncellenirken aynı anda kullanıcılar sunucuyu yani bahsedilen paketi kullanmaya devam edebilirler. Bunu bir örnek üzerinden inceleyelim,

    Nginx’in 1.24 sürümü sistemimizde kurulu olsun. Servisi başlattığımızda bu sürüme ait process’ler çalışmaya başlar. Nginx’i kesinti oluşturmadan 1.25 sürümüne yükselttiğimizde eski process’ler hemen sonlandırılmaz. Yeni sürüme ait process’ler başlatılır ve yeni bağlantılar bu process’lere yönlendirilir. Eski process’ler ise mevcut bağlantıları tamamladıktan sonra sonlandırılır.

    Bu sayede mevcut bağlantılar kesilmeden servis yeni sürüm üzerinden çalışmaya devam eder.

    Aynı şekilde, bir process tarafından açık tutulan dosya silinse bile process bu dosyayı kullanmaya devam edebilir. Çünkü dosya silindiğinde ilk olarak dosya adı ile inode arasındaki bağlantı kaldırılır. Process’in açık dosya tanımlayıcısı ise hâlâ aynı inode’a erişmeye devam eder. Dosyanın verileri, process dosyayı kapattığında ve dosyaya ait başka bir hard link kalmadığında diskten tamamen kaldırılır.

    Doruk Hoca da bunu bir müzik dosyasını oynatırken başka bir terminalden dosyayı silerek göstermişti. Dosyanın ismi dizinden kaldırılmasına rağmen müzik uygulaması dosyayı açık tuttuğu için müzik çalmaya devam etmişti.

    Bu durum aynı zamanda silinen dosyaları geri kurtarmak istediğimizde de işimize yarar. Dosya bir process tarafından kullanılmaya devam ediyorsa process kapanmadan dosyayı geri kurtarabiliriz.

    Bunu uygulamalı olarak göstermek için öncelikle tail ile bir dosyayı kullanan process oluşturuyorum.

    bash
    mehmet@debian ~$ tail -f silinecek-dosya.txt

    ardından başka bir terminale geçip önce dosyayı siliyorum sonrasında

    bash
    mehmet@debian ~$ ps aux | grep tail

    komutunu girip

    çıktısını alıyorum. tail sürecini çalıştıran process numarası ikinci sütunda yazıyor. /proc dizini altında 2698 numaralı dizine gidersem orada silinmiş dosyayı bulabilirim. İlgili dizini listelemek için,

    bash
    mehmet@debian ~$ ls -l /proc/2698/fd

    komutunu çalıştırdığımda çıktım:

    şeklinde oluyor. Burada da görülebileceği üzere “3 -» ..” ile başlayan dosya benim dosyam. O dosyayı kopyaladığımda tekrar dosyamı kullanabilir hale geleceğim. Bunun için,

    bash
    mehmet@debian ~$ cp /proc/2698/fd/3 ~/nasilkurtardimama

    dosyamı kopyalayıp tekrar okuduğumda sorunsuz şekilde dosyamı kurtarmış oluyorum.

    Linux sistemlerde paketleri depodan bulup indiren, bağımlılıklarını çözen ve paket yönetim sürecini baştan sona yöneten araçların yanında, elindeki paket dosyasını kuran, kaldıran ve kurulu paketlerin kaydını tutan daha düşük seviyeli paket yöneticileri de bulunur.

    Bunlar debian’da dpkg, rocky’de ise rpm’dir.

    Bu paket yöneticileri tek başına herhangi bir depoya bağlanıp paketleri çekip kuramaz. Eksik bağımlılıkları indiremez.

    dpkg ile bir paketi kurmak için,

    bash
    mehmet@debian ~$ apt download nano
    mehmet@debian ~$ sudo dpkg -i nano_7.2-2ubuntu0.2_amd64.deb

    komutlarını girerek kurulumu tamamlayabiliriz (apt ile yalnızca .deb dosyasını indirdim, bunu hızlı bir şekilde örnek olarak göstermek için yaptım) .

    Paket hakkında bilgi almak için,

    bash
    mehmet@debian ~$ dpkg -l nano
    bash
    mehmet@rocky ~$ rpm -q nano

    Paket kurulduğunda sistemimizde kuracağı dosyaları incelemek için,

    bash
    mehmet@debian ~$ dpkg -L nano
    bash
    mehmet@rocky ~$ rpm -ql nano

    şeklinde komut girebiliriz.

    dpkg -L ile ters yönde çalışan yani, bir dosyanın hangi paketle birlikte geldiğini gösteren bir komutumuz daha var:

    bash
    mehmet@debian ~$ dpkg -S /usr/share/doc/nano

    doğrudan dosyayı verip hangi paket ile birlikte geldiğini öğrenebiliyoruz.

    Not: Kurduğumuz paketleri manuel olarak kaldırmak için iki adet komutumuz bulunuyor. remove ve purge. remove, paketi kaldırır ancak yapılandırma dosyalarını bırakır. purge ise paketi yapılandırma dosyalarıyla birlikte kaldırır. Her ikisi de kullanılmayan bağımlılıkları kendiliğinden silmez.

    dpkg -L çıktısıyla nano paketini inceleyelim.
    komutunu çalıştırdığımızda nano paketiyle birlikte sistemimize kurulan dosya ve dizinleri görebiliriz. Komutun çıktısı uzun olduğu için çıktıyı parçalara ayırarak inceledim.

    Çıktının başında /, /etc, /usr ve /usr/share gibi dizinler yer alıyor. dpkg -L yalnızca dosyaları değil, pakete kayıtlı olan dizinleri de listeler.

    /usr/bin/nano, nano editörünü çalıştırdığımız asıl dosyadır. /usr/bin/rnano ise nano’nun bazı işlemleri sınırlandırılmış biçimde çalışan sürümüdür.

    /etc/nanorc, nano’nun sistem genelinde geçerli olan yapılandırma dosyasıdır. Nano’nun çalışma biçimiyle ilgili genel ayarlar bu dosya üzerinden yapılabilir.

    /usr/share/doc/nano dizini altında paketle ilgili açıklamalar, değişiklik kayıtları, telif bilgileri ve örnek yapılandırma dosyaları bulunur. AUTHORS, programı geliştiren kişiler hakkında bilgi verirken README ve faq.html gibi dosyalar programın kullanımıyla ilgili bilgiler içerir. Sonu .gz ile biten belgeler daha az yer kaplamaları için sıkıştırılmıştır.

    /usr/share/doc-base altında bulunan dosyalar, nano ile birlikte kurulan belgelerin Debian’ın belge sistemine tanıtılmasını sağlar. Böylece sistemdeki belge görüntüleme araçları nano’ya ait belgeleri bulabilirler.

    /usr/share/info/nano.info.gz, nano hakkında daha ayrıntılı bilgiler içeren GNU Info belgesidir.

    /usr/share/lintian/overrides/nano dosyasında, nano paketi Lintian ile denetlenirken göz ardı edilecek uyarılar belirtilir. Lintian normalde şüpheli gördüğü durumlar için uyarı verir. Ancak paket geliştiricisi bu durumun bilinçli olarak yapıldığını ve hata olmadığını biliyorsa ilgili uyarıyı bu dosyada istisna olarak tanımlayabilir. Yani bu nano’nun çalışırken doğrudan kullandığı bir dosya değildir.

    /usr/share/man altında nano, rnano ve nanorc için hazırlanmış man sayfaları bulunur.

    Not: Aynı isimde ancak farklı konuları anlatan birden fazla man sayfası bulunabilir. Örneğin passwd hem kullanıcı parolasını değiştirmek için kullandığımız komutun hem de /etc/passwd dosya biçiminin adıdır. man 1 passwd komutuyla parola değiştirme komutunun, man 5 passwd komutuyla ise /etc/passwd dosyasının yapısını anlatan man sayfasını açabiliriz. Yalnızca man passwd yazdığımızda man, bölümleri sırayla arar ve bulduğu ilk sayfayı gösterir.

    Kullanılan man sayfaları şu şekildedir:

    Bölümİçerik
    man 1 Kullanıcı komutları
    man 2Sistem çağrıları
    man 3Kütüphane fonksiyonları
    man 4Özel dosyalar ve aygıtlar
    man 5Dosya biçimleri ve yapılandırma dosyaları
    man 6Oyunlar
    man 7Standartlar, protokoller ve genel kavramlar
    man 8Sistem yöneticisi komutları
    man 9Kernel içi rutinler

    Çıktının büyük bölümünü /usr/share/nano altındaki .nanorc dosyaları oluşturuyor. Bu dosyaların her biri Python, JavaScript, HTML, CSS, SQL ve Markdown gibi farklı programlama dilleri veya dosya türleri için söz dizimi renklendirme kurallarını içerir. Nano bir dosyanın türünü tespit ettiğinde ilgili .nanorc dosyasındaki kuralları kullanarak metni renklendirir.

    Kısacası nano paketi yalnızca /usr/bin/nano dosyasından oluşmaz. Bunun yanında paketle birlikte yapılandırma dosyaları, belgeler, kullanım kılavuzları, paket denetim bilgileri ve farklı dosya türleri için hazırlanan söz dizimi renklendirme kuralları da sistemimize kurulur.

    Yaptığımız güncellemeleri geri almamızı gerektirebilecek durumlarla karşı karşıya gelebiliriz. Örneğin birden fazla paketi aynı anda güncelledik ve güncellemenin ardından sistem düzgün çalışmamaya başladı. Böyle bir durumda hangi paketleri güncellediğimizi tek tek aramak yerine doğrudan tek bir komutla bunları ortaya çıkartabiliriz.

    Rocky’de,

    bash
    mehmet@rocky ~$ sudo dnf history list

    komutunu yazdığımızda

    gibi bir çıktı ile karşılaşırız. Burada

    bash
    mehmet@rocky ~$ sudo dnf history info ID

    ile seçtiğimiz bir işlemin detaylarına ulaşabiliriz.

    İşlemi geri almak için,

    bash
    mehmet@rocky ~$ sudo dnf history undo ID

    komutunu çalıştırırız.

    Bir paketi ve dosyalarını istediğimiz bir dizine kurmak içinse Rocky’de,

    bash
    mehmet@rocky ~$ sudo dnf --installroot=/opt/rocky-kok --releasever=9 install nano

    komutunu çalıştırırız. Burada –installroot diyerek kurulacak dizini verdik, -releasever diyerek kullandığımız Rocky’nin sürümünü söyledik.

    debianda, apt3.2 öncesinde olmayan ancak şimdi doğrudan apt komutu üzerinden bakabileceğimiz bir history bulunuyor.

    bash
    mehmet@debian ~$ apt history-list

    komutunu girdiğimizde

    çıktısını alıyoruz. Bu çıktı da yapılan işlemin türü, hangi pakete işlem yapıldığı ve tarihi gibi bilgiler yer alıyor.

    bash
    mehmet@debian ~$ apt history-info ID

    komutunu girerek seçtiğimiz herhangi bir işlem hakkında detaylı bilgi edinebiliriz. Örneğin,

    nano paketinin indirilmesine dair olan işlemdeki bilgiler yer alıyor.

    Burada yaptığımız işlemi geri almak istediğimizde,

    bash
    mehmet@debian ~$ sudo apt history-undo ID

    komutunu girerek

    paketi geri silebiliriz.

    Belirli bir işlemden sonraki tüm işlemleri geri almak için,

    bash
    mehmet@debian ~$ sudo apt history-rollack ID

    komutunu gireriz,

    ve o işlemden sonraki ilk işlemden itibaren yapılan işler geri alınır.

    Not: debian (apt) tarafında bu özellik apt 3.2 sürümüyle birlikte geldi. Kullandığınız eski sürümlerde bu özellik yer almıyor. Mesela kullandığım 24.04 Ubuntu Server LTS’te bu komutları kullanamazken 26.04 sürümünde kullanabildim.

    Not: Sistemdeki APT paketini tek başına daha yeni bir sürüme yükseltmek teknik olarak mümkün olsa da güvenli ve pratik bir yöntem değildir. APT, sistemdeki birçok temel paket ve kütüphaneyle birlikte çalıştığı için yeni sürüm farklı bağımlılıklar gerektirebilir. Bu özellikleri kullanmak için yalnızca APT’yi değiştirmek yerine ilgili sürümü destekleyen dağıtım sürümüne geçmek daha doğru olur.

    Sıkıştırma ve Paketleme

    Dosyalarda tekrar eden verilerin daha az yer kaplaması için onları sıkıştırırız.

    Bunu basit bir örnek üzerinden inceleyelim. Elimizde,

    AAAAAAAAAABBBBBCCCC

    şeklinde bir veri olduğunu düşünelim. Burada her harfi tek tek tutmak yerine bu veri,

    10A5B4C

    olarak yazıldığında daha az yer kaplayacaktır. Kullandığımız sıkıştırma araçları da temelde bu mantıkla hareket ederler.

    Kullanabileceğimiz açık kaynaklı, özgür yazılım sıkıştırma araçları: gzip, xz …

    Sıkıştırma araçlarında hız ile sıkıştırma oranı arasında genellikle ters bir denge bulunur. Dosyayı daha fazla küçültmeye çalışan araçlar bunun için daha fazla işlem yaptığı için sıkıştırmayı daha yavaş tamamlayabilir. Hızlı çalışan araçlar ise işlemi daha kısa sürede tamamlar ancak dosyayı aynı ölçüde küçültemeyebilir.

    gzip dosya_adi veya xz dosya_adi şeklinde basit bir kullanımları vardır. gz ile sıkıştırdığımız dosyaları gunzip ile, xz ile sıkıştırdığımız dosyaları unxz ile yeniden açabiliriz.

    gzip ve xz gibi sıkıştırma araçları aslında kendilerine verilen veri akışını sıkıştırırlar. Bu nedenle tek bir dosyayı doğrudan sıkıştırabilirler ancak bir dizini, içerisindeki bütün dosyalar ve alt dizinlerle birlikte tek başlarına arşivleyemezler.

    gzip aracının -r seçeneğiyle dizinin içindeki dosyaları ayrı ayrı sıkıştırmak mümkündür. Ancak bu işlem dizinin tamamını tek bir .gz dosyası haline getirmez. Bu işlemi yaptıktan sonra geri almak için /dizin/* şeklinde dizindeki tüm dosyaları kapsayacak şekilde gunzip yapmamız gerekir.

    gzip’in sıkıştırma derecesini arttırmak için 1 ile 9 arasında parametre değerleri verebiliriz.

    Dizin yapısını koruyarak bütün dosyaları tek yerde toplamak istediğimizde tar kullanmamız gerekir.

    Devamını okumak için…