Острота Bash для удаления только старых ядер

Я видел много потоков о том, как к свободному пространству на / разделе начальной загрузки и это - моя цель также. Однако я только интересуюсь удалением старых ядер и не каждого из них, но текущего.

Мне нужно решение быть остротой, так как я буду запускать скрипт от Марионетки, и я не хочу иметь дополнительные файлы, лежащие вокруг. До сих пор я получил следующее:

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

Быть более точным, что это делает в данный момент, следующее:

  • Перечислите весь Linux -* пакеты и распечатайте их имена.
  • Только перечислите тех, которые имеют числа и сортируют их, возвращая обратный результат. Таким образом, более старые ядра перечислены в последний раз.
  • Распечатайте только результаты, которые следуют за текущим ядром
  • С тех пор существует некоторый Linux - {изображение, заголовки} результаты, удостоверяется, что я не произведу чистку ничего связанного со своим текущим ядром
  • Назовите склонными произвести чистку

Это работает, но я уверен, что решение может быть более изящным и что это безопасно для продуктивной среды, так как по крайней мере 20 из наших серверов запускают Ubuntu.

Спасибо за внимание, Alejandro.

23
задан 7 January 2014 в 19:34

8 ответов

Выглядит достаточно красиво, всего несколько комментариев. Два первых комментария делают команду более безопасной, а третий и четвертый делают ее немного короче. Не стесняйтесь следовать или игнорировать любой из них. Хотя я настоятельно советую следовать первым двум. Вы хотите убедиться, что это максимально безопасно. Я имею в виду серьезно. Вы добавляете sudo apt-get -y purge в какой-то автоматически сгенерированный список пакетов. Это так зло ! :)

  1. Перечисление всех linux-* даст вам много ложных срабатываний, например (пример из моего вывода) linux-sound-base. Хотя они могут быть отфильтрованы позже остальной вашей командой, я бы лично чувствовал себя безопаснее, не перечисляя их в первую очередь. Лучше контролировать, какие пакеты вы хотите удалить. Не делайте вещи, которые могут иметь неожиданные результаты. Поэтому я бы начал с

    dpkg -l linux-{image,headers}-*
    
  2. Ваше регулярное выражение "перечислять только те, у которых есть числа", на мой взгляд, немного слишком просто. Например, есть пакет linux-libc-dev:amd64, когда вы работаете в 64-битной системе. Ваше регулярное выражение будет соответствовать. Вы не хотите, чтобы это соответствовало. Правда, если вы следовали моему первому совету, то linux-libc-dev:amd64 все равно не попадут в список, но все же. Мы знаем больше о структуре номера версии, чем простой факт «есть число». Кроме того, как правило, рекомендуется заключать в кавычки регулярные выражения, просто чтобы предотвратить возможные неверные интерпретации оболочкой. Поэтому я бы сделал эту команду egrep

     egrep '[0-9]+\.[0-9]+\.[0-9]+'
    
  3. Тогда есть сортировка. Почему вы сортируете? Так как вы собираетесь удалить все ядра (кроме текущего) в любом случае, важно ли удалять старые, прежде чем новые? Я не думаю, что это имеет значение. Или вы делаете это только для того, чтобы затем использовать sed для «печати только результатов, которые идут после текущего ядра»? Но ИМО это кажется слишком сложным. Почему бы просто не отфильтровать результаты, соответствующие вашему текущему ядру, как вы уже делаете с grep -v, и все будет готово? Честно говоря, если я возьму первую часть вашей команды (с двумя интегрированными моими предыдущими предложениями), на моей машине я получу

    $ 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
    

    Удаляя эту сортировку / sed, я получаю

    $ 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
    

    Таким образом, ваша более сложная команда фактически пропустит два пакета на моей машине, которые я хотел бы удалить (теперь возможно, что эти linux-image-extra-* вещи зависят от linux-image-* вещей и, следовательно, будут удалены в любом случае, но это может ' больно делать это явным). Во всяком случае, я не вижу смысла в вашей сортировке; простой grep -v без причудливой предварительной обработки должен быть в порядке, возможно, даже лучше. Я сторонник принципа KISS. Это облегчит вам понимание или отладку позже. Кроме того, без сортировки она немного более эффективна;)

  4. Это чисто эстетическое решение, но вы получите тот же результат с этим немного более коротким вариантом. : -)

    $ 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
    

В результате я получаю более простую и безопасную команду

$ 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

Поскольку вы действительно хотите очистить свой раздел /boot совершенно другой подход будет заключаться в том, чтобы перечислить содержимое /boot, использовать dpkg -S для определения пакетов, к которым принадлежат отдельные файлы, отфильтровать те, которые принадлежат текущему ядру, и удалить полученные пакеты. Но мне больше нравится ваш подход, потому что он также найдет устаревшие пакеты, такие как linux-headers-*, которые устанавливаются не в /boot, а в /usr/src.

0
ответ дан 7 January 2014 в 19:34
  • 1
    Что касается теперь, я решил выполнение Ваших шагов, I' ll, возможно, пытаются собственными драйверами завтра после моего представления проекта не рискнуть повреждать систему снова ahah огромное спасибо! Вы знаете, как я мог препятствовать тому, чтобы это произошло в следующий раз, когда я выполняю dist-обновление? – Alessandro 28 June 2015 в 22:05

Я написал этот скрипт, который удаляет пакеты "linux- *", которые имеют меньшую версию, чем загруженная в данный момент. Я думаю, что нет необходимости проверять состояние пакета. Команда запрашивает подтверждение перед очисткой пакетов. Если вы не хотите этого, добавьте опцию -y в команду apt-get.

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

Однако, чтобы иметь возможность оставлять настраиваемое количество запасных ядер, я рекомендую использовать мой скрипт linux-purge с опцией --keep. См. здесь для получения дополнительной информации о сценарии.

0
ответ дан 7 January 2014 в 19:34

TL; DR: пропустите к нижней части.

Это немного длиннее все же. Я сломаю его для Вас:

  1. dpkg -l linux-{image,headers}-* | awk '/^ii/{print $2}' Точно так же, как предложенный Malte. Перечисляет соответствующие файлы ядра.
  2. egrep '[0-9]+\.[0-9]+\.[0-9]+' Также предложенный Malte в качестве более безопасного способа выбрать только файлы ядра путем поиска номера версии.
  3. Так как мы теперь возможно перечисляем и изображение и пакеты заголовка, именование пакета может варьироваться так, у нас есть это awk обходное решение, которое необходимо для вида awk 'BEGIN{FS="-"}; {if ($3 ~ /[0-9]+/) print $3"-"$4,$0; else if ($4 ~ /[0-9]+/) print $4"-"$5,$0}' Результатом является новый столбец с номером версии перед исходным именем пакета как ниже:

    $ 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. Теперь мы должны отсортировать список для предотвращения удаления любых более новых изображений, чем то, которое в настоящее время работает. sort -k1,1 --version-sort -r предоставление нас это:

    $ 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. Теперь разделите текущие и более новые файлы ядра sed -e "1,/$(uname -r | cut -f1,2 -d"-")/d" | grep -v -e `uname -r | cut -f1,2 -d"-"` предоставление нас это:

    $ 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. Теперь снимите изоляцию с первого столбца, с которым мы добавили awk '{print $2}' для получения точно, что мы хотим:

    $ 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. Теперь мы можем подать это к диспетчеру пакетов, чтобы автоматически удалить все и реконфигурировать личинку:

    Я рекомендую делать пробный прогон сначала (хотя для Ваших сценариев имеет целью, это не могло бы быть практично, если у Вас есть крупная среда),

    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
    

    Теперь, если все смотрит хорошее разрешение, и на самом деле удалите его с:

    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
    

Еще раз смысл этой "остроты" должен удалить только ядра, БОЛЕЕ СТАРЫЕ, чем в настоящее время рабочее ядро (который оставляет любые недавно установленные ядра все еще доступными),

Спасибо сообщает мне, как это работает на Вас и если Вы могли бы улучшить его!

3
ответ дан 7 January 2014 в 19:34
  • 1
    Если это имеет значение dkms НЕ является гарантией что это won' t происходят снова - в зависимости от обновлений под рукой. Вещами, связанными с новыми Ядрами и X, является общий множитель в этом (Один опыт года с ASUS GTX 780 и всеми возможными драйверами) – Hannu 28 June 2015 в 21:33

Вы можете просто перечислить каталог / boot, чтобы увидеть имеющиеся у вас версии ядра, используя команду 'ls'. Затем используйте 'sudo apt-get -y purge "xxx", где "xxx" заменяется номером версии, которую вы хотите удалить. Позаботьтесь, чтобы это была не та версия, которую вы сейчас используете !!.

0
ответ дан 7 January 2014 в 19:34

Установите bikeshed (apt install bikeshed) и позвоните purge-old-kernels от имени пользователя root.

$ sudo purge-old-kernels
0
ответ дан 7 January 2014 в 19:34
  • 1
    @Hannu ничто не гарантия, " к полному объему law" – mchid 28 June 2015 в 22:37

Быстрый ответ, объяснение по запросу:

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
0
ответ дан 7 January 2014 в 19:34
  • 1
    @Alessandro также, dkms должен быть установлен в то время, когда модуль Nvidia компилируется. – mchid 28 June 2015 в 22:40

Я очень устал от всей этой ненужной сложности и создал пакет Python, который делает однострочную тривиальной:

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

Установите его с помощью

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

. 112] https://github.com/mrts/ubuntu-old-kernel-cleanup .

Надеюсь, это поможет и другим.

0
ответ дан 7 January 2014 в 19:34
  • 1
    Я выполнил сценарий, и он работал. Я получил " Успех! Частные данные смонтировались в [/tmp/encryptfs...], Но когда я пытаюсь получить доступ к папке, это отклоняет меня, потому что у меня нет необходимых полномочий просмотреть папку. Тогда я открыл наутилус и открыл папку, но в папке существует только файл, названный " Access-Your-Private-Data.desktop" и README.txt. После чтения txt файла это говорит мне нажимать на .desktop файл или выполнять команду Вы вышеизложенный. Я нажал на .desktop файл, и ничего не происходит. – NuWin 30 June 2015 в 08:28
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

Работает все время, и даже Ubuntu 17.10

0
ответ дан 7 January 2014 в 19:34

Другие вопросы по тегам:

Похожие вопросы: