当前位置: 首页>>技术教程>>正文


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

, ,

问题描述

在网上浏览 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,只保留当前版本!

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

  • 执行这个命令是否安全?

  • 这个命令是如何工作的?即解释这么大的命令的小部分

  • 如果此命令用于某些不同的目的,那么实现作者声称的功能的正确命令是什么?

当我试图自己推论时,我变得非常困惑和沮丧。这个命令是如何工作的,它包含了许多很难用谷歌搜索的 /|\*^ 字符。

我正在寻找一步一步的翻译&我在互联网上找不到这个命令的解释!

最佳方法

我会说:不要以当前的形式使用它

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

  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 选项,因此系统会要求您确认即将对系统进行的更改。

Explanation

  • dpkg -l 输出所有包的列表。在这种情况下,它只会列出以 linux- 作为名称开头的包。

  • |(管道)将左侧命令的输出(我们称之为 stdout )通过管道传输到右侧命令的输入(我们称之为 stdin )。

  • sed 是一个使用正则表达式操作字符串的工具。在这种情况下,它操作管道左侧的命令输出和已安装包的过滤器(依赖于 dpkg 给出的 ii )。在这种情况下它甚至被嵌套。在这里解释 sed 的整个使用太难了,因为它的使用对于复杂的正则表达式非常复杂。 (\(.*\)-\([^0-9]\+\)" 是一个正则表达式的例子。

  • Regular expressions 被非常广泛地用于根据它们所代表的表达式查找匹配项。 \1 是替换引用,用于执行某种通用 search-and-replace (引用第一个 ‘hit’ 和 1 )。正则表达式本身不会造成任何伤害。但是,如果他们以错误的方式操作输入,他们可以让您删除错误的包,甚至进行 shell 注入。在这种情况下,它看起来像是一种根据 uname -r 提供的版本查找内核包名称的方法。

  • uname -r 输出当前运行的内核版本。

  • xargs 将管道左侧的输入行作为参数附加到命令中。在这种情况下,每一行的内核版本被转换为水平空格分隔的列表并附加到 sudo apt-get 命令。

  • sudo apt-get -y purge [packagename] 清除(删除所有内容)给定的包(作为参数)。

Alternatives

很多问题可能已经被问到了。到目前为止我发现的相关内容:

次佳方法

你要求一个 step-by-step 解释所以这里是:

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 语法的理解程度。并且有关于这两个主题的整本书。

第三种方法

我首先剖析命令,阅读每个命令的 man 页面。

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

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

  • uname -r uname 打印系统信息

uname – print system information

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

-r, –kernel-release print the kernel release

uname -r 的输出然后通过更多的正则表达式通过管道传送到 sed,其输出被传递到 xargs

因此 xargssed 输出转换为包名称并将它们传递给 sudo apt-get purge -ysudo apt-get purge -y 会自动回答 ‘yes’ 的所有提示:

-y, –yes, –assume-yes Automatic yes to prompts; assume “yes” as answer to all prompts and run non-interactively. If an undesirable situation, such as changing a held package, trying to install a unauthenticated package or removing an essential package occurs then apt-get will abort. Configuration Item: APT::Get::Assume-Yes.

总而言之,这个命令似乎可以满足您的需求,但要确定我们必须翻译 sed 的正则表达式。

我刚跑:

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

这是一个屏幕截图:

所有旧内核版本 iirc。

参考资料

本文由Ubuntu问答整理, 博文地址: https://ubuntuqa.com/article/12065.html,未经允许,请勿转载。