Я видел много потоков о том, как к свободному пространству на / разделе начальной загрузки и это - моя цель также. Однако я только интересуюсь удалением старых ядер и не каждого из них, но текущего.
Мне нужно решение быть остротой, так как я буду запускать скрипт от Марионетки, и я не хочу иметь дополнительные файлы, лежащие вокруг. До сих пор я получил следующее:
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
Быть более точным, что это делает в данный момент, следующее:
Это работает, но я уверен, что решение может быть более изящным и что это безопасно для продуктивной среды, так как по крайней мере 20 из наших серверов запускают Ubuntu.
Спасибо за внимание, Alejandro.
Выглядит достаточно красиво, всего несколько комментариев. Два первых комментария делают команду более безопасной, а третий и четвертый делают ее немного короче. Не стесняйтесь следовать или игнорировать любой из них. Хотя я настоятельно советую следовать первым двум. Вы хотите убедиться, что это максимально безопасно. Я имею в виду серьезно. Вы добавляете sudo apt-get -y purge
в какой-то автоматически сгенерированный список пакетов. Это так зло ! :)
Перечисление всех linux-*
даст вам много ложных срабатываний, например (пример из моего вывода) linux-sound-base
. Хотя они могут быть отфильтрованы позже остальной вашей командой, я бы лично чувствовал себя безопаснее, не перечисляя их в первую очередь. Лучше контролировать, какие пакеты вы хотите удалить. Не делайте вещи, которые могут иметь неожиданные результаты. Поэтому я бы начал с
dpkg -l linux-{image,headers}-*
Ваше регулярное выражение "перечислять только те, у которых есть числа", на мой взгляд, немного слишком просто. Например, есть пакет linux-libc-dev:amd64
, когда вы работаете в 64-битной системе. Ваше регулярное выражение будет соответствовать. Вы не хотите, чтобы это соответствовало. Правда, если вы следовали моему первому совету, то linux-libc-dev:amd64
все равно не попадут в список, но все же. Мы знаем больше о структуре номера версии, чем простой факт «есть число». Кроме того, как правило, рекомендуется заключать в кавычки регулярные выражения, просто чтобы предотвратить возможные неверные интерпретации оболочкой. Поэтому я бы сделал эту команду egrep
egrep '[0-9]+\.[0-9]+\.[0-9]+'
Тогда есть сортировка. Почему вы сортируете? Так как вы собираетесь удалить все ядра (кроме текущего) в любом случае, важно ли удалять старые, прежде чем новые? Я не думаю, что это имеет значение. Или вы делаете это только для того, чтобы затем использовать 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. Это облегчит вам понимание или отладку позже. Кроме того, без сортировки она немного более эффективна;)
Это чисто эстетическое решение, но вы получите тот же результат с этим немного более коротким вариантом. : -)
$ 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
.
Я написал этот скрипт, который удаляет пакеты "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
. См. здесь для получения дополнительной информации о сценарии.
TL; DR: пропустите к нижней части.
Это немного длиннее все же. Я сломаю его для Вас:
dpkg -l linux-{image,headers}-* | awk '/^ii/{print $2}'
Точно так же, как предложенный Malte. Перечисляет соответствующие файлы ядра.egrep '[0-9]+\.[0-9]+\.[0-9]+'
Также предложенный Malte в качестве более безопасного способа выбрать только файлы ядра путем поиска номера версии.Так как мы теперь возможно перечисляем и изображение и пакеты заголовка, именование пакета может варьироваться так, у нас есть это 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
Теперь мы должны отсортировать список для предотвращения удаления любых более новых изображений, чем то, которое в настоящее время работает. 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
Теперь разделите текущие и более новые файлы ядра 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
Теперь снимите изоляцию с первого столбца, с которым мы добавили 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
Теперь мы можем подать это к диспетчеру пакетов, чтобы автоматически удалить все и реконфигурировать личинку:
Я рекомендую делать пробный прогон сначала (хотя для Ваших сценариев имеет целью, это не могло бы быть практично, если у Вас есть крупная среда),
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
Еще раз смысл этой "остроты" должен удалить только ядра, БОЛЕЕ СТАРЫЕ, чем в настоящее время рабочее ядро (который оставляет любые недавно установленные ядра все еще доступными),
Спасибо сообщает мне, как это работает на Вас и если Вы могли бы улучшить его!
Вы можете просто перечислить каталог / boot, чтобы увидеть имеющиеся у вас версии ядра, используя команду 'ls'. Затем используйте 'sudo apt-get -y purge "xxx", где "xxx" заменяется номером версии, которую вы хотите удалить. Позаботьтесь, чтобы это была не та версия, которую вы сейчас используете !!.
Установите bikeshed
(apt install bikeshed
) и позвоните purge-old-kernels
от имени пользователя root.
$ sudo purge-old-kernels
Быстрый ответ, объяснение по запросу:
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
Я очень устал от всей этой ненужной сложности и создал пакет 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 .
Надеюсь, это поможет и другим.
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