
Что делает следующий код?
Я нашел его в интернете, скопировал и вставил в терминал, но когда я установил новое ядро, оно обнаружило только старое.
sudo apt-get remove --purge $(dpkg -l 'linux-image-*' | sed '/^ii/!d;/'"$(uname -r | sed "s/\(.*\)-\([^0-9]\+\)/\1/")"'/d;s/^[^ ]* [^ ]* \([^ ]*\).*/\1/;/[0-9]/!d')
решение1
Давайте разберем код по частям (для моей системы):
$ dpkg -l 'linux-image-*'
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name Version Architecture Description
+++-=============================-===================-===================-================================================================
un linux-image-3.0 <none> <none> (no description available)
ii linux-image-3.13.0-32-generic 3.13.0-32.57 amd64 Linux kernel image for version 3.13.0 on 64 bit x86 SMP
ii linux-image-extra-3.13.0-32-g 3.13.0-32.57 amd64 Linux kernel extra modules for version 3.13.0 on 64 bit x86 SMP
ii linux-image-generic 3.13.0.32.38 amd64 Generic Linux kernel image
$ dpkg -l 'linux-image-*' | sed '/^ii/!d'
ii linux-image-3.13.0-32-generic 3.13.0-32.57 amd64 Linux kernel image for version 3.13.0 on 64 bit x86 SMP
ii linux-image-extra-3.13.0-32-generic 3.13.0-32.57 amd64 Linux kernel extra modules for version 3.13.0 on 64 bit x86 SMP
ii linux-image-generic 3.13.0.32.38 amd64 Generic Linux kernel image
$ uname -r | sed 's/\(.*\)-\([^0-9]\+\)/\1/'
3.13.0-32
$ dpkg -l 'linux-image-*' | sed '/^ii/!d' | sed "/$(uname -r | sed 's/\(.*\)-\([^0-9]\+\)/\1/')/d"
ii linux-image-generic 3.13.0.32.38 amd64 Generic Linux kernel image
$ dpkg -l 'linux-image-*' | sed '/^ii/!d' | sed "/$(uname -r | sed 's/\(.*\)-\([^0-9]\+\)/\1/')/d" | sed 's/^[^ ]* [^ ]* \([^ ]*\).*/\1/'
linux-image-generic
$ dpkg -l 'linux-image-*' | sed '/^ii/!d' | sed "/$(uname -r | sed 's/\(.*\)-\([^0-9]\+\)/\1/')/d" | sed 's/^[^ ]* [^ ]* \([^ ]*\).*/\1/' | sed '/[0-9]/!d'
## No output
Так что это ничего не даст:
$ sudo apt-get remove --purge $(dpkg -l 'linux-image-*' | sed '/^ii/!d;/'"$(uname -r | sed "s/\(.*\)-\([^0-9]\+\)/\1/")"'/d;s/^[^ ]* [^ ]* \([^ ]*\).*/\1/;/[0-9]/!d')
Как вы видетеэто было очень близко к удалению моего текущего метапакета ядра linux-image-generic 3.13.0.32.38 amd64 Generic Linux kernel image
(благодаря этой последней sed '/[0-9]/!d'
строке), что неверно.
В двух словах, эта часть sed
имеет несколько проблем. Вам следует избегать ее, чтобы удалить ваши старые ядра.
РЕДАКТИРОВАТЬ:
Я уже говорил, что sed
команда имеет проблемы. Ради расширения я собираюсь удалить последние две строки с формой, которая на самом деле должна работать в моем текущем сценарии.
Последние две строки в измененном виде:
sed -r 's/^[^ ]* *(([a-z]|-)*)(-[a-z]*) *(([0-9]|-)*)\..*/\1-\4\3/'
Так:
$ dpkg -l 'linux-image-*' | sed '/^ii/!d;/'"$(uname -r |
sed "s/\(.*\)-\([^0-9]\+\)/\1/")"'/d' |
sed -r 's/^[^ ]* *(([a-z]|-)*(-[a-z]*) *(([0-9]|\.|-)*)\..*/\1\-\4\3/'
Выделения:
linux-image-3.13.0.32-generic
Это очень опасно!!
Теперь покажу, что это сделает с моей системой, --dry-run
написав полную apt-get remove
команду:
$ sudo apt-get remove --dry-run $(dpkg -l 'linux-image-*' |
sed '/^ii/!d;/'"$(uname -r | sed "s/\(.*\)-\([^0-9]\+\)/\1/")"'/d' |
sed -r 's/^[^ ]* *(([a-z]|-)*)(-[a-z]*) *(([0-9]|\.|-)*)\..*/\1\-\4\3/')
Reading package lists... Done
Building dependency tree
Reading state information... Done
Note, selecting 'linux-image-3.13.0-32-generic' for regex 'linux-image-3.13.0.32-generic'
The following package was automatically installed and is no longer required:
linux-headers-generic
Use 'apt-get autoremove' to remove it.
The following packages will be REMOVED:
linux-generic linux-image-3.13.0-32-generic
linux-image-extra-3.13.0-32-generic linux-image-generic
0 upgraded, 0 newly installed, 4 to remove and 0 not upgraded.
Remv linux-generic [3.13.0.32.38]
Remv linux-image-generic [3.13.0.32.38]
Remv linux-image-extra-3.13.0-32-generic [3.13.0-32.57]
Remv linux-image-3.13.0-32-generic [3.13.0-32.57]
Как видите, он удалит все мои текущие ядра. Также обратите внимание, что это всего лишь симуляция, соответствующая моему текущему сценарию, и оригинал sed
можно улучшить.
** Обратите внимание, что реальный код будет работать, если выполнить reboot
обновление ядра послеОли уже упоминал.
ПРАВКА2:
Вот простой, но надежный скрипт, который рассмотрит все ситуации и удалит старые ядра:
#!/bin/bash
kernels=( $(grep -Po "^linux-image-[^-]+-[^-]+-generic\b" < <(dpkg --get-selections)) )
cur_rel=$(grep -Po ".*(?=-[a-z]*$)" < <(uname -r))
for kernel in "${kernels[@]}"; do
ker_rel=$(grep -Po "[0-9].*(?=-[a-z]*)" <<< "$kernel")
dpkg --compare-versions "$ker_rel" gt "$cur_rel" && { echo "Please Restart your computer first"; break; }
dpkg --compare-versions "$ker_rel" lt "$cur_rel" && sudo apt-get remove "$kernel"
done
Если у вас есть версия, которая новее текущей, это даст вам предупреждение о необходимости перезагрузить компьютер. Также обратите внимание, что старые ядра сохраняются по веской причине: если вы каким-то образом испортите свое текущее ядро, сделав систему нестабильной, то вы сможете загрузить любое старое ядро.
решение2
Это попытка удалить ядра, которые не являются текущими.
Существует множество фрагментов кода, которые делают что-то подобное иэто не хороший пример. Он может легко удалить более новые ядра, чем текущие, и, следовательно, метапакет, который устанавливается ( linux-generic
и т. д.), если вы обновились и не перезагрузились.