这个删除旧内核的命令可以安全使用吗?

这个删除旧内核的命令可以安全使用吗?

在网上浏览 Ubuntu 文章时,我遇到了这个命令:

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

作者说这是一个单行命令,它将删除所有以前版本的Linux,只保留当前版本

我实际上正在寻找这样的命令,但我不太确定它有多安全。我想知道:

  • 执行该命令是否安全?
  • 这个命令是如何工作的?即解释这么大的命令的一小部分
  • 如果此命令有其他用途,那么什么命令才是正确的,才能实现作者声称它要做的事情呢?

当我尝试自己推断时,我感到非常困惑和沮丧。这个命令如何工作,因为它包含大量/|\*^字符,这些字符很难在 Google 上找到。

我正在寻找一步一步翻译和解释对于这个命令,我在互联网上无法找到!

答案1

我想说:不要以目前的形式使用它

  1. 它会在不询问您的情况下进行更改。该apt-get -y purge部分允许单行程序开始执行清除包,而无需您的确认。如果脚本中存在任何错误,那么您可能会拧紧

  2. 没有来源,没有给出作者。它的来源在这里很重要。如果它来自经过彻底测试的系统包,我们可以追踪对它进行的测试。如果是随机来源,我们不能相信它。

  3. dpkg -l没有 也能正常运行sudo。我不明白为什么原作者认为这是必要的。

运用常识

删除有害部分并删除以 root 身份运行的任何内容。

例如,将其简化为:

dpkg -l 'linux-*' | sed '/^ii/!d;/'"$(uname -r | sed "s/\(.*\)-\([^0-9]\+\)/\1/")"'/d;s/^[^ ]* [^ ]* \([^ ]*\).*/\1/;/[0-9]/!d'

这只是只输出东西并运行具有常规用户权限。同意删除这些内核后,您可以附加 | xargs sudo apt-get purge自己确认。它-y故意没有这个选项,所以系统会要求您确认即将对系统进行的更改。

解释

  • dpkg -l输出所有软件包的列表。在本例中,它仅列出软件包开始linux-作为名称。
  • |(管道)将左边命令的输出(我们称之为stdout)通过管道传输到右边命令的输入(我们称之为stdin)。
  • sed是一个使用以下方法操作字符串的工具常用表达。在本例中,它操纵管道左侧命令的输出并过滤已安装的软件包(依赖于ii给出的dpkg)。在本例中它甚至是嵌套的。在这里解释 的整个用法太难了sed,因为它的用法非常复杂,带有复杂的正则表达式。(\(.*\)-\([^0-9]\+\)"是正则表达式的一个例子。
  • 常用表达被广泛用于根据它们所代表的表达式查找匹配项。\1是替换引用,用于执行某种通用搜索和替换(引用第一个“命中” 1)。正则表达式本身不会造成任何伤害。但是,如果它们以错误的方式操纵输入,它们可能会让您删除错误的软件包,甚至进行 shell 注入。在这种情况下,它看起来像是一种根据提供的版本查找内核软件包名称的方法uname -r
  • uname -r输出当前运行的内核版本。
  • xargs将管道左侧输入的行作为参数附加到命令中。在这种情况下,每行上的内核版本将转换为水平空格分隔的列表并附加到命令中sudo apt-get
  • sudo apt-get -y purge [packagename]清除(删除所有内容)给定的包(作为参数)。

备择方案

可能已经有人问过这个问题了。我目前找到的相关问题如下:

答案2

您要求一步一步的解释,因此如下:

sudo dpkg -l 'linux-*'

列出linux-包名中以 开头的包

| sed

并将列表导入sed

"s/\(.*\)-\([^0-9]\+\)/\1/")"'/d;s/^[^ ]* [^ ]* \([^ ]*\).*/\1/;/[0-9]/!d'

这将使用非常复杂的正则表达式来编辑列表

| xargs

xargs它将把新列表输入到

sudo apt-get -y purge

这将清除这些包而不给你改变主意的机会。

或者更准确的说法是,它会将该列表发送到清除命令中,然后就此打住。无论是否有任何东西被清除——重要的是——被清除了什么取决于前面命令的输出。

它安全吗?在这种情况下,一切都取决于你找到它的帖子的作者对正则表达式和sed语法的理解程度。关于这两个主题都有整本书。

答案3

我首先分析这些命令,然后阅读man每个命令的页面。

  • dpkg -l:列出软件包,因此dpkg -l linux-*会列出所有以(通常是内核)开头的软件包linux-

  • sed:的输出通过dpkg -l linux-*管道传输到sed几个sed解码的正则表达式。

  • uname -r uname打印系统信息

uname—打印系统信息

-r句柄专门打印内核版本:

-r, --kernel-release 打印内核版本

uname -r然后将的输出sed通过更多正则表达式传输到xargs

因此将输出xargs转换sed为包名称并将它们传递给sudo apt-get purge -y自动对所有提示回答“是”的包:

-y, --yes, --assume-yes 自动对提示回答“是”;假设所有提示的答案都是“是”,并以非交互方式运行。如果出现不良情况,例如更改保留的软件包、尝试安装未经认证的软件包或删除必需的软件包,则 apt-get 将中止。配置项:APT::Get::Assume-Yes。

总的来说,这个命令将要做你想做的事,但要确定我们必须翻译sed的正则表达式。

我刚刚跑了:

dpkg -l 'linux-*' | sed '/^ii/!d;/'"$(uname -r | sed "s/\(.*\)-\([^0-9]\+\)/\1/")"'/d;s/^[^ ]* [^ ]* \([^ ]*\).*/\1/;/[0-9]/!d'  

以下是截图:

在此处输入图片描述

据我回忆,所有内核版本都是旧的。

答案4

此脚本的一个不太危险的版本删除了未使用和过期的内核,它rc在输出的行首匹配dpkg,而不是ii。 (见https://askubuntu.com/a/18807/220802对这些标志进行解释。)就我而言,这完全匹配所有未受保护的内核包/etc/apt/apt.conf.d/01autoremove-kernels

例如:

# sed -n '/to keep/,$p' /etc/apt/apt.conf.d/01autoremove-kernels
# Kernel versions list to keep:
5.4.0-58.64
5.4.0-60.67
# Kernel packages (version part) to protect:
5\.4\.0-58-generic
5\.4\.0-60-generic
*/

# dpkg -l 'linux-*' | sed '/^rc/!d;/'"$(uname -r | sed "s/\(.*\)-\([^0-9]\+\)/\1/")"'/d;s/^[^ ]* [^ ]* \([^ ]*\).*/\1/;/[0-9]/!d'
linux-image-5.3.0-18-generic
linux-image-5.3.0-19-generic
linux-image-5.3.0-45-generic
linux-image-5.4.0-21-generic
linux-image-5.4.0-26-generic
linux-image-5.4.0-28-generic
linux-image-5.4.0-31-generic
linux-image-5.4.0-33-generic
linux-image-5.4.0-40-generic
linux-image-5.4.0-42-generic
linux-image-5.4.0-48-generic
linux-image-5.4.0-52-generic
linux-image-5.4.0-53-generic
linux-image-5.4.0-56-generic
linux-modules-5.3.0-18-generic
linux-modules-5.3.0-19-generic
linux-modules-5.3.0-45-generic
linux-modules-5.4.0-21-generic
linux-modules-5.4.0-26-generic
linux-modules-5.4.0-28-generic
linux-modules-5.4.0-31-generic
linux-modules-5.4.0-33-generic
linux-modules-5.4.0-40-generic
linux-modules-5.4.0-42-generic
linux-modules-5.4.0-48-generic
linux-modules-5.4.0-52-generic
linux-modules-5.4.0-53-generic
linux-modules-5.4.0-56-generic
linux-modules-extra-5.3.0-18-generic
linux-modules-extra-5.3.0-19-generic
linux-modules-extra-5.3.0-45-generic
linux-modules-extra-5.4.0-21-generic
linux-modules-extra-5.4.0-26-generic
linux-modules-extra-5.4.0-28-generic
linux-modules-extra-5.4.0-31-generic
linux-modules-extra-5.4.0-33-generic
linux-modules-extra-5.4.0-40-generic
linux-modules-extra-5.4.0-42-generic
linux-modules-extra-5.4.0-48-generic
linux-modules-extra-5.4.0-52-generic
linux-modules-extra-5.4.0-53-generic
linux-modules-extra-5.4.0-56-generic

现在您可以通过管道传输该消息| xargs apt purge -y。请注意,省略该-y标志将导致操作中止。

然后,您可以检查/boot目录中是否有更多旧内核的残留。在我的例子中,还有更多文件挂在周围,不再被跟踪apt,这些文件被删除,并被ls /boot/*-5.4.0-{00..56}* 2>/dev/null小心地传送到| xargs rm -rf

相关内容