如何优雅地删除不需要的内核?

如何优雅地删除不需要的内核?

我的磁盘空间有点不足,我发现有几个内核占用了空间,我可能永远不会使用这些内核。有一个名为“计算机管理员”的程序可以清理所有内容(以及许多您不想清理的内容),但我找不到它。有更好的替代方案吗?

非常感谢!

答案1

  1. 首先,你需要查看当前使用的内核,因为你不能删除它。你可以使用以下命令查看:

    uname -r

  2. 然后,您可以使用以下命令查看已安装的内核:

    dpkg --list | grep linux-image

  3. 你也可以使用 apt-get 删除多余的内核,如下所示:

    sudo apt-get purge linux-image-xxx-x-generic

其中 xxx-x 是您要删除的内核。请记住,您不能删除当前正在使用的内核(uname -r 的输出)。您应该保留第二个内核作为备份,以防第一个内核因某种原因失败。

另一种选择是使用 Ubuntu Tweak 的 Janitor,它可以选择删除未使用的内核。

答案2

我为此编写了一个 Bash 函数。分享即关爱,因此我们开始介绍我在 Debian 5 和 6 以及 Ubuntu 10.04 和 12.10 版本上成功使用的 Bash 函数。随着时间的推移,它有所改进,但从未让我失望。它使“决策过程”自动化。

注意:请随意指出缺陷并提出改进建议,我会尽力采纳。

function prune-kernels
{
        [[ -f "/etc/debian_version" ]] || { echo -e "\033[01;32mERROR:\033[00m This has only been tested on Debian/Ubuntu."; return; }
        [[ -e "/vmlinuz" ]] || { echo -e "\033[01;32mERROR:\033[00m Expected /vmlinuz to exist."; return; }
        [[ "$UID" -eq "0" ]] || local SUDO=sudo
        # Figure out the name of the newest and the previous kernel
        local OLDKRNL=$(readlink -f /vmlinuz.old)
        local NOWKRNL=$(readlink -f /vmlinuz)
        # If vmlinuz doesn't exist, Also prune "/vmlinuz.old"?
        [[ -e "/vmlinuz.old" ]] || OLDKRNL="$NOWKRNL"
        # Also prune "/vmlinuz.old"? If so, pretend old and new have the same name to skip only the new one
        [[ "$1" == "--old" ]] && local OLDKRNL="$NOWKRNL"
        # Strip path
        OLDKRNL="${OLDKRNL##*/vmlinuz-}"
        NOWKRNL="${NOWKRNL##*/vmlinuz-}"
        local VERSIONS=$(echo $(for krnl in /boot/vmlinuz-*; do echo "${krnl##*/vmlinuz-}"; done) $(for krnl in $(dpkg -l|command grep 'linux-image'|command grep '^ii'|command grep -v 'meta-package'|command grep 'linux-image-[[:digit:]]\.[[:digit:]]*\.[[:digit:]]'|awk '{print $2}'); do echo ${krnl##linux-image-}; done)|sort|uniq|sed -e "s:$NOWKRNL::g;s:$OLDKRNL::g;s:$(uname -r)::g")
        echo -ne "\033[01;32mSkipping \033[01;33mthe following kernels:\033[00m $NOWKRNL"
        [[ "$(uname -r)" == "$NOWKRNL" ]] || { echo -ne ", $(uname -r)"; }
        echo -ne " (\033[0;32mcurrently running\033[00m)"
        [[ "$OLDKRNL" == "$NOWKRNL" ]] || echo -ne ", $OLDKRNL (\033[0;33mold kernel\033[00m)"
        echo ""
        # Remove packages
        local PACKAGES=$(for i in $VERSIONS; do echo -n "linux-image-$i linux-headers-$i "; done)
        if [[ -n "$PACKAGES" ]]; then
                echo -e "\033[0;32m[STEP 1] \033[01;33mRemoving packages\033[00m"
                $SUDO apt-get remove $PACKAGES || { echo -e "\033[01;31mSeems that apt-get was not successful, aborting.\033[00m"; return; }
        else
                echo -e "\033[01;32mNo packages need to be removed.\033[00m"
        fi
        # Remove any remaining kernel images etc from /boot
        local FILES=$(for fname in $(for i in $VERSIONS; do echo -n "/boot/abi-$i /boot/initrd.img-$i config-$i System.map-$i vmcoreinfo-$i vmlinuz-$i "; done); do [[ -f "$fname" ]] && { echo -n "$fname "; }; done)
        if [[ -n "$FILES" ]]; then
                echo -e "\033[0;32m[STEP 2] \033[01;33mNow removing remaining files:\033[00m $FILES"
                $SUDO rm -f $FILES
        else
                echo -e "\033[01;32mNothing else to clean up.\033[00m"
        fi
}

将该函数放入文件中并从您的文件中获取它,.bashrc或者只是从 shell 临时获取它然后运行它。除非您对apt-get设置做了一些花哨的事情,否则这会在采取行动之前提示。

该函数还接受一个参数--old来删除除正在运行的内核之外的所有内核。默认情况下,它将跳过修剪过程中的运行内核和旧/vmlinuz.old内核( )。

另请注意:此功能即使在运行的内核比当前(/vmlinuz链接)和旧(/vmlinuz.old链接)内核更旧的情况下也能很好地工作。

披露:几乎 1:1 复制自我之前在这里回答过

答案3

关于这个话题我有一个很有帮助的老答案:如何查找旧内核

它故意不删除这些包,因为这对我的肩膀。如果安装新内核后您没有重新启动,该脚本将删除新内核。它不会牵着您的手。

我编写了一个命令的快速变体,可以显示除当前内核之外的所有内容。您可以以此为基础进行删除,但无论您用它做什么,您都需要检查您是否没有删除刚刚安装的内核。

dpkg -l | grep -Eo "^.i +linux-(image|headers)[^ ]+" | cut -c 5- | grep -v `uname -r`

相关内容