以下代码起什么作用?
我在互联网上找到了它,所以我将它复制并粘贴到终端,但是当我安装新内核时,它只检测到旧内核。
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
** 请注意,如果在内核升级后执行以下代码,则实际代码将会起作用:Oli 已经提到。
编辑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
。如果您进行了升级但未重新启动,它可能会轻易删除比当前版本更新的内核,从而删除安装的元包(等)。