这个删除旧内核的命令安全吗?


21

浏览Internet上的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版本,仅保留当前版本

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

  • 执行此命令是否安全?
  • 该命令如何工作?即解释这么大的命令的一小部分
  • 如果此命令用于其他目的,那么实现作者要求的正确命令是什么?

当我尝试自己推断所有内容时,我会感到非常困惑和沮丧。它包含了这是如何指挥工作众多/|\*,和^字符,这是很难为谷歌。

我正在寻找此命令的逐步翻译和解释,我无法在Internet上找到它!


1
这似乎不是您引用的命令,但是我一直在tuxtweaks.com/2010/10/…中使用该命令删除旧内核,而没有任何问题。此页面还说明了命令的作用。
user68186

4
@UriHerrera apt-get autoremove不建议我删除任何较旧的内核。如果我不删除它们,它们将堆积直到我/boot的空间不足并且更新失败。您对此有参考吗?
gertvdijk

1
它对我有用,只要有内核的新更新,它就会说以后不再需要以下软件包等,它列出了我以前拥有的内核。
Uri Herrera

我的答案已被主持人删除,因此我在这里发表评论:有关脚本的说明,请参见本文。我不明白为什么脚本的一部分s/^[^ ]* [^ ]* \([^ ]*\).*/\1/不是简单的s/^[^ ]* \([^ ]*\).*/\1/。该脚本不是很健壮或优雅。例如,为什么在从输出中提取软件包名称之前检查当前内核?作为替代方案,请sudo apt-get autoremove --purge在一些最新版本的Ubuntu中清除大多数旧内核,例如Xubuntu 15.10。
jarno

Answers:


27

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

  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)。正则表达式本身不会造成任何伤害。但是,如果他们以错误的方式操纵输入,他们可以让您删除错误的程序包甚至进行外壳注入。在这种情况下,这似乎是一种根据所提供的版本查找内核软件包名称的方法uname -r
  • uname -r 输出正在运行的内核的当前版本。
  • xargs将管道左侧输入的行附加为命令的参数。在这种情况下,每行的内核版本将转换为水平的空格分隔列表,并附加到sudo apt-get命令中。
  • sudo apt-get -y purge [packagename] 清除(删除所有内容)给定的程序包(作为参数)。

备择方案

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


1
这条命令看起来很恐怖的节点应该是什么破裂,就像这样的/(.*)-([^0-9]\+)/\1/")"'/d;s/^[^ ] * [^] *([^] *)。* / \ 1 /; /
Bhavesh Diwan

上面所说的命令在这个答案中会优雅地清除旧内核吗?还是仍然倾向于自动删除更好?
Bhavesh Diwan

4
@ Z9iT这些是正则表达式。它们用于根据它们表示的表达式来查找匹配项,并且\1是进行通用搜索和替换的替换控件。对于删除任何程序包,我已经明确表示自己(我的看法):使用常识。不要让脚本自动更改系统。验证它会做什么。总是。
gertvdijk

您提供的替代功能不会清除相应的linux-header软件包。
jarno 2015年

然后只需执行apt-get autoremove,即可检测到不再需要这些标头。
Ben-Nabiy Derush

7

您要求逐步说明,因此请按以下步骤进行:

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


6

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

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

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

  • uname -r uname打印系统信息

uname-打印系统信息

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

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

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

因此,xargssed输出转换为程序包名称,并将其传递sudo apt-get purge -y给所有名称,然后自动对所有提示回答“是”:

-y,-是,-假定是自动提示。对所有提示均回答“是”,并且非交互式运行。如果发生不良情况,例如更改保留的软件包,尝试安装未经身份验证的软件包或删除基本软件包,则apt-get将中止。配置项:APT :: Get :: Assume-是。

总而言之,尽管可以肯定地知道我们必须翻译的正则表达式,但该命令似乎可以完成您想要的操作sed

我跑了:

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

这是屏幕截图:

在此处输入图片说明

所有旧内核版本iirc。


翻译此sed表达的锻炼方式是什么?
Bhavesh Diwan

2
我想立即了解它,可能需要一些时间;)
赛斯,2013年


@ Z9iT我太懒了,无法将脚本的说明从链接的文章复制到答案中,所以我想这就是Seth删除我的答案的原因。但是我认为链接的文章正是您在Internet上寻找的东西。我还告诉您一种删除旧内核的更安全的方法,尽管它可以保留2-3个内核,以防万一,并且可能无法在所有当前的Ubuntu版本中使用。
jarno 2015年

@jarno我删除了它,因为Z9iT询问的是特定命令,而不是删除旧内核的安全方法。这可能仍然有意义,但是在评论中而不是回答:)(就像您所做的那样)
塞斯(Seth
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.