Sadece eski çekirdeği silmek için Bash bir liner


23

/ Boot bölümünde nasıl boş yer açılacağı konusunda birçok konu gördüm ve bu da benim amacım. Ancak, sadece eski çekirdekleri silmekle ilgileniyorum, her birini değil şimdikileri.

Senaryoyu bir liner olmak için çözmeliyim çünkü senaryoyu Puppet'ten çalıştıracağım ve etrafta fazladan dosya eklemek istemiyorum. Şimdiye kadar aşağıdakileri aldım:

dpkg -l linux-* | awk '/^ii/{print $2}' | egrep [0-9] | sort -t- -k3,4 --version-sort -r | sed -e "1,/$(uname -r | cut -f1,2 -d"-")/d" | grep -v -e `uname -r | cut -f1,2 -d"-"` | xargs sudo apt-get -y purge

Daha kesin olmak gerekirse, şu anda yaptığı şey şudur:

  • Tüm linux- * paketlerini listeleyin ve isimlerini yazdırın.
  • Yalnızca sayıları olanları listele ve sırala, sonuçtan geri döndür. Bu şekilde, daha eski çekirdekleri en son listelenir.
  • Yalnızca geçerli çekirdeğin peşinden giden sonuçları yazdır
  • Bazı linux- {image, headers} sonuçları olduğundan, mevcut çekirdeğimle ilgili hiçbir şeyi temizlemeyeceğimden emin olun
  • Arındırma için uygun çağrı

Bu işe yarar, ancak çözümlerin daha şık olabileceğinden ve üretim ortamları için güvenli olduğundan eminim, çünkü sunucularımızdan en az 20 tanesi Ubuntu kullanıyor.

Zaman ayırdığınız için teşekkürler Alejandro.



Komut dosyasına kaydedilmemişse, bir linerinizi nasıl kullanıyorsunuz?
jarno

Yanıtlar:


25

Yeterince güzel görünüyor, sadece birkaç yorum. İlk iki yorum komutu daha güvenli kılarken, üçüncü ve dördüncü kısım biraz daha kısa hale getirir. Bunlardan herhangi birini takip etmekten veya görmezden gelmekten çekinmeyin. Yine de ilk ikisini izlemenizi şiddetle tavsiye edeceğim. Mümkün olduğunca güvenli olduğundan emin olmak istiyorsun. Gerçekten diyorum. sudo apt-get -y purgeOtomatik olarak oluşturulan bir paket listesine atıyorsunuz . Bu çok kötü ! :)

  1. Tümünü listelemek linux-*size (benim çıktımdan örnek) gibi birçok yanlış pozitif kazandırır linux-sound-base. Bunlar daha sonra emrinizde kalanlar tarafından filtrelenmiş olsalar bile, ilk başta onları listelememekten kendimi daha güvenli hissediyorum. Hangi paketleri kaldırmak istediğinizi daha iyi kontrol edin. Beklenmeyen sonuçlara neden olabilecek şeyler yapmayın. Bu yüzden başlamak isterim

    dpkg -l linux-{image,headers}-*
  2. "Sadece sayıları olanları listele" ye regex bence biraz basittir. Örneğin, linux-libc-dev:amd6464 bit bir sistemde paket var . Regex'iniz eşleşecek. Eşleşmesini istemiyorsun. Kuşkusuz, ilk tavsiyeme uyduysanız, linux-libc-dev:amd64yine de listelenmeyecektir. Bir sürüm numarasının yapısı hakkında "bir sayı var" ifadesinden daha fazlasını biliyoruz. Ek olarak, genellikle kabuğun olası yanlış yorumlamaları önlemek için regex'leri alıntılamak iyi bir fikirdir. Bu yüzden o egrep komutunu yapardım

     egrep '[0-9]+\.[0-9]+\.[0-9]+'
  3. Sonra bu sıralama şey var. Neden sıralıyorsun Zaten tüm çekirdekleri (mevcut olan hariç) kaldıracağınız için, daha yenilerini önce eskileri çıkarmak sizin için önemli mi? Bunun bir fark yaratacağını sanmıyorum. Yoksa sadece bunu yapıyor musunuz, böylece sed"Yalnızca geçerli çekirdekten sonra gelen sonuçları yazdır" seçeneğini kullanabilirsiniz . Ancak IMO bu çok karmaşık bir duygu. Neden halihazırda yaptığınız gibi ve halihazırdaki çekirdeğinize karşılık gelen sonuçları filtrelemeyin grep -v? Dürüst olmak gerekirse, emrinizin ilk bölümünü alırsam (önceki iki önerim entegre edilmiş halde), makinemde alıyorum

    $ dpkg -l linux-{image,headers}-* | awk '/^ii/{print $2}' | egrep '[0-9]+\.[0-9]+\.[0-9]+' | sort -t- -k3,4 --version-sort -r | sed -e "1,/$(uname -r | cut -f1,2 -d"-")/d" | grep -v -e `uname -r | cut -f1,2 -d"-"`
    linux-image-3.8.0-34-generic
    linux-image-3.5.0-44-generic

    Bu sıralama / sed şeyler kaldırarak alırım

    $ dpkg -l linux-{image,headers}-* | awk '/^ii/{print $2}' | egrep '[0-9]+\.[0-9]+\.[0-9]+' | grep -v -e `uname -r | cut -f1,2 -d"-"`
    linux-image-3.5.0-44-generic
    linux-image-3.8.0-34-generic
    linux-image-extra-3.5.0-44-generic
    linux-image-extra-3.8.0-34-generic

    Bu yüzden, daha karmaşık olan komutunuz makinemdeki iki paketi özlüyordu, çıkarmak linux-image-extra-*istiyordum (şimdi bu şeylerin şeylere bağlı linux-image-*olması ve bu nedenle yine de kaldırılması mümkün, ancak açık hale getirilmesi mümkün değil). Her halükarda, sıralamadaki noktanızı göremiyorum; grep -vfantezi ön işleme olmadan basit , muhtemelen daha iyi, iyi olmalı. Ben KISS ilkesinin bir savunucusuyum. Daha sonra anlamanız veya hata ayıklamanız kolaylaşacaktır. Ayrıca, sıralama olmadan biraz daha verimli;)

  4. Bu tamamen estetiktir ancak bu biraz daha kısa değişkenlerle aynı çıktıyı elde edersiniz. :-)

    $ dpkg -l linux-{image,headers}-* | awk '/^ii/{print $2}' | egrep '[0-9]+\.[0-9]+\.[0-9]+' | grep -v $(uname -r | cut -d- -f-2)
    linux-image-3.5.0-44-generic
    linux-image-3.8.0-34-generic
    linux-image-extra-3.5.0-44-generic
    linux-image-extra-3.8.0-34-generic

Sonuç olarak, daha basit ve daha güvenli komutla bitirdim.

$ dpkg -l linux-{image,headers}-* | awk '/^ii/{print $2}' | egrep '[0-9]+\.[0-9]+\.[0-9]+' | grep -v $(uname -r | cut -d- -f-2) | xargs sudo apt-get -y purge

Gerçekte temizlemek istediğimiz için /bootbölümü, tamamen farklı bir yaklaşım içeriğini listelemek için olacağını /boot, kullanım dpkg -Sbireysel dosyalar olan çekirdekle dahil olanlara dışarı filtre, ait oldukları paketleri belirlemek ve elde edilen paketleri kaldırın. Fakat yaklaşımınızı daha çok seviyorum, çünkü bunlar aynı zamanda üzerine linux-headers-*kurulmamış /boot, fakat olmayan eski paketleri de bulacak /usr/src.


Yanıtınız için @Malte, girişiniz için teşekkürler. İlk iki adımı çok net buluyorum ve oneliner'ı gerçekten daha güvenli hale getiriyorlar. Ancak, son iki adımınızın yeni çekirdekleri görmezden gelip onları da temizlediğine inanıyorum. En azından çözümünüzü bir sunucu üzerinde denedim ve bu istenmeyen bir şeyi kaldırmıştı.
Alejandro

İlginç. Biri üçüncü ve dördüncü önerimin de dahil olduğu, biri olmayan bir komutla bana iki çıktı verebilir misiniz? Artı çıktı uname -r. Benim için iyi çalışıyor. Neden sizin durumunuzda işe yaramadığını görmek ilginç olurdu.
Malte Skoruppa

1
Size PM denedim ama herhangi bir e-posta adresi bulamadım bu yüzden çıktımı buraya gönderirim : hastebin.com/raleyigowe.vhdl uname -r sunucumun linux-image-3.8.0-34 kullandığını gösteriyor bazen bir sunucu daha yeni bir çekirdeği indirdi, ancak henüz kurmadı. Bu yüzden sadece eski çekirdekleri çıkarmanın bir yolunu arıyordum .
Alejandro

Bu komut mevcut çekirdeğimin başlık dosyasını seçti ve bu istenmeyen bir durumdu.
Mark Stosberg

1
@MalteSkoruppa, uname -rüretir 4.8.0-36-generic dışlamak başarısız olan linux-headers-4.8.0-36listeden.
Mark Stosberg

7

Şu anda önyüklenenden daha düşük bir sürümü olan "linux- *" paketlerini kaldıran bu betiği yazdım. Paket durumunu test etmek gerekli olmadığını düşünüyorum. Komut paketleri tasfiye etmeden önce onayınızı ister. Bunu istemiyorsanız, apt-get komutuna -y seçeneğini ekleyin.

sudo apt-get purge $(dpkg-query -W -f'${Package}\n' 'linux-*' |
sed -nr 's/.*-([0-9]+(\.[0-9]+){2}-[^-]+).*/\1 &/p' | linux-version sort | 
awk '($1==c){exit} {print $2}' c=$(uname -r | cut -f1,2 -d-))

Ancak, yapılandırılabilir miktarda yedek çekirdek bırakabilmek için betiğimi seçeneği linux-purgeile birlikte kullanmanızı öneririm --keep. Senaryo hakkında daha fazla bilgi için buraya bakın .


3

TL; DR: en alta atla.

Yine de biraz daha uzun. Senin için parçalayacağım:

  1. dpkg -l linux-{image,headers}-* | awk '/^ii/{print $2}'Malte'nin önerdiği gibi. İlgili çekirdek dosyalarını listeler.
  2. egrep '[0-9]+\.[0-9]+\.[0-9]+' Ayrıca Malte tarafından sürüm numarası arayarak yalnızca çekirdek dosyalarını seçmenin daha güvenli bir yolu olarak önerilmiştir.
  3. Şimdi hem resmi hem de başlık paketlerini listeleyebildiğimiz için, paket isimleri değişebilir, bu yüzden sıralama için gerekli olan bu geçici çözümü bulduk awk 'BEGIN{FS="-"}; {if ($3 ~ /[0-9]+/) print $3"-"$4,$0; else if ($4 ~ /[0-9]+/) print $4"-"$5,$0}'. Sonuç, aşağıdaki orijinal paket isminden önceki sürüm numarasına sahip yeni bir sütundur:

    $ dpkg -l linux-{image,headers}-* | awk '/^ii/{print $2}' | egrep '[0-9]+\.[0-9]+\.[0-9]+' | awk 'BEGIN{FS="-"}; {if ($3 ~ /[0-9]+/) print $3"-"$4,$0; else if ($4 ~ /[0-9]+/) print $4"-"$5,$0}'
    3.11.0-23 linux-headers-3.11.0-23
    3.11.0-23 linux-headers-3.11.0-23-generic
    3.11.0-24 linux-headers-3.11.0-24
    3.11.0-24 linux-headers-3.11.0-24-generic
    3.11.0-26 linux-headers-3.11.0-26
    3.11.0-26 linux-headers-3.11.0-26-generic
    3.11.0-23 linux-image-3.11.0-23-generic
    3.11.0-24 linux-image-3.11.0-24-generic
    3.11.0-26 linux-image-3.11.0-26-generic
    3.8.0-35 linux-image-3.8.0-35-generic
    3.11.0-23 linux-image-extra-3.11.0-23-generic
    3.11.0-24 linux-image-extra-3.11.0-24-generic
    3.11.0-26 linux-image-extra-3.11.0-26-generic
    3.8.0-35 linux-image-extra-3.8.0-35-generic
  4. Şimdi, çalışmakta olandan daha yeni görüntüleri kaldırmamak için listeyi sıralamalıyız. sort -k1,1 --version-sort -rbize bunu vererek:

    $ dpkg -l linux-{image,headers}-* | awk '/^ii/{print $2}' | egrep '[0-9]+\.[0-9]+\.[0-9]+' | awk 'BEGIN{FS="-"}; {if ($3 ~ /[0-9]+/) print $3"-"$4,$0; else if ($4 ~ /[0-9]+/) print $4"-"$5,$0}' | sort -k1,1 --version-sort -r
    3.11.0-26 linux-image-extra-3.11.0-26-generic
    3.11.0-26 linux-image-3.11.0-26-generic
    3.11.0-26 linux-headers-3.11.0-26-generic
    3.11.0-26 linux-headers-3.11.0-26
    3.11.0-24 linux-image-extra-3.11.0-24-generic
    3.11.0-24 linux-image-3.11.0-24-generic
    3.11.0-24 linux-headers-3.11.0-24-generic
    3.11.0-24 linux-headers-3.11.0-24
    3.11.0-23 linux-image-extra-3.11.0-23-generic
    3.11.0-23 linux-image-3.11.0-23-generic
    3.11.0-23 linux-headers-3.11.0-23-generic
    3.11.0-23 linux-headers-3.11.0-23
    3.8.0-35 linux-image-extra-3.8.0-35-generic
    3.8.0-35 linux-image-3.8.0-35-generic
  5. Şimdi sed -e "1,/$(uname -r | cut -f1,2 -d"-")/d" | grep -v -e `uname -r | cut -f1,2 -d"-"`bize şu anki ve daha yeni çekirdek dosyalarını çıkarın :

    $ dpkg -l linux-{image,headers}-* | awk '/^ii/{print $2}' | egrep '[0-9]+\.[0-9]+\.[0-9]+' | awk 'BEGIN{FS="-"}; {if ($3 ~ /[0-9]+/) print $3"-"$4,$0; else if ($4 ~ /[0-9]+/) print $4"-"$5,$0}' | sort -k1,1 --version-sort -r | sed -e "1,/$(uname -r | cut -f1,2 -d"-")/d" | grep -v -e `uname -r | cut -f1,2 -d"-"`
    3.11.0-23 linux-image-extra-3.11.0-23-generic
    3.11.0-23 linux-image-3.11.0-23-generic
    3.11.0-23 linux-headers-3.11.0-23-generic
    3.11.0-23 linux-headers-3.11.0-23
    3.8.0-35 linux-image-extra-3.8.0-35-generic
    3.8.0-35 linux-image-3.8.0-35-generic
  6. Şimdi awk '{print $2}'tam olarak istediğimizi elde etmek için eklediğimiz ilk sütunu soyun:

    $ dpkg -l linux-{image,headers}-* | awk '/^ii/{print $2}' | egrep '[0-9]+\.[0-9]+\.[0-9]+' | awk 'BEGIN{FS="-"}; {if ($3 ~ /[0-9]+/) print $3"-"$4,$0; else if ($4 ~ /[0-9]+/) print $4"-"$5,$0}' | sort -k1,1 --version-sort -r | sed -e "1,/$(uname -r | cut -f1,2 -d"-")/d" | grep -v -e `uname -r | cut -f1,2 -d"-"` | awk '{print $2}'
    linux-image-extra-3.11.0-23-generic
    linux-image-3.11.0-23-generic
    linux-headers-3.11.0-23-generic
    linux-headers-3.11.0-23
    linux-image-extra-3.8.0-35-generic
    linux-image-3.8.0-35-generic
  7. Artık her şeyi otomatik olarak kaldırmak ve grub'u yeniden yapılandırmak için bunu paket yöneticisine aktarabiliriz:

    Öncelikle kuru çalışma yapmanızı öneririm (ancak komut dizileriniz için bu, geniş bir ortamınız varsa pratik olmayabilir)

    dpkg -l linux-{image,headers}-* | awk '/^ii/{print $2}' | egrep '[0-9]+\.[0-9]+\.[0-9]+' | awk 'BEGIN{FS="-"}; {if ($3 ~ /[0-9]+/) print $3"-"$4,$0; else if ($4 ~ /[0-9]+/) print $4"-"$5,$0}' | sort -k1,1 --version-sort -r | sed -e "1,/$(uname -r | cut -f1,2 -d"-")/d" | grep -v -e `uname -r | cut -f1,2 -d"-"` | awk '{print $2}' | xargs sudo apt-get --dry-run remove

    Şimdi, eğer her şey yolunda görünüyorsa, devam edin ve aslında şunu kaldırın:

    dpkg -l linux-{image,headers}-* | awk '/^ii/{print $2}' | egrep '[0-9]+\.[0-9]+\.[0-9]+' | awk 'BEGIN{FS="-"}; {if ($3 ~ /[0-9]+/) print $3"-"$4,$0; else if ($4 ~ /[0-9]+/) print $4"-"$5,$0}' | sort -k1,1 --version-sort -r | sed -e "1,/$(uname -r | cut -f1,2 -d"-")/d" | grep -v -e `uname -r | cut -f1,2 -d"-"` | awk '{print $2}' | xargs sudo apt-get -y purge

Bir kez daha, bu "tek astar" ın tüm amacı, şu anda çalışan çekirdeğe göre yalnızca YAŞLI olan çekirdeği çıkarmaktır (bu, yeni kurulmuş olan çekirdeği hala kullanılabilir durumda bırakır)

Teşekkürler, bunun sizin için nasıl çalıştığını ve nasıl geliştirebileceğinizi bilmeme izin verin!



1

'Ls' komutunu kullandığınız çekirdek sürümlerini görmek için / boot dizinini kolayca listeleyebilirsiniz. Sonra 'sudo apt-get -y temizleme "xxx"' i kullanın; burada "xxx", kaldırmak istediğiniz sürüm numarası ile değiştirilir. Şu anda çalıştırdığınız sürüm olmadığından emin olun !!


1
Bir liner emri istediler. Çözümünüz 1'den fazla satıra ihtiyaç duyuyor
Anwar


0

Hızlı bir cevap, istek üzerine açıklama:

dpkg -l 'linux-image-[0-9]*' | 
awk -v current="$(uname -r)" '!/^i/ || $2~current {next} {print $2}' |
sed '$d' | 
xargs echo sudo apt-get autoremove

2
Bunu açıklamayı içerecek şekilde genişletmeyi öneririm (veya istersen istersen). :)
Eliah Kagan 11

@EliahKagan, bence senaryonun bir anlamı yok. Yüklenmesini istemediğiniz paketleri neden atlayın? Komut dosyası, mevcut olandan daha yeni bazı çekirdekleri kaldırabilir veya bazı eski sed '$d'komutları komutla kaydedebilir . Betik, linux-başlık paketlerini veya çıkarılacak çekirdek paketleriyle ilgili diğer paketleri silmez, ayrıca paketlerin yapılandırma dosyalarını silmez. Bunun yerine cevabımı kullanmanızı tavsiye ederim.
jarno

@EliahKagan Gerçekten de komut dosyası hiçbir paketi kaldırmaz, ancak çalıştırabileceğiniz komutu yazdırır (by echo) apt-get.
jarno

0

Tüm bu gereksiz karmaşıklıktan gerçekten bıktım ve bir liner önemsiz hale getiren bir Python paketi yarattım:

ubuntu-old-kernel-cleanup | xargs sudo apt-get -y purge

İle yükleyin

sudo pip install git+http://github.com/mrts/ubuntu-old-kernel-cleanup.git

Https://github.com/mrts/ubuntu-old-kernel-cleanup adresinde daha fazla bilgi alabilirsiniz .

Umarım bu da başkalarına yardımcı olur.


Bunu denedim ama hata alıyorum: "ubuntu-old-kernel-cleanup: command not found"
Hibe

Sonra yürütülebilir arama yolunda değil. Eğer onunla yüklediniz mi sudo pip install ...yukarıda açıklandığı gibi? sudoaslında önemli, aksi halde pipbazı kullanıcı dizinlerine kurar ve kabuk bu dizinde çalıştırılabilir dosyalar için arama yapmayabilir.
Mrts

0
sudo dpkg -l 'linux-*' | sed '/^ii/!d;/'"$(uname -r | sed "s/\(.*\)-\([^0-9]\+\)/\1/")"'/d;s/^[^ ]* [^ ]* \([^ ]*\).*/\1/;/[0-9]/!d' | xargs sudo apt-get -y purge

Her zaman çalışır, hatta ubuntu 17,10


Benim için bu kaldırmaya çalışır linux-libc-dev:amd64, bu istenmeyen.
Malte Skoruppa
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.