此命令是否可以安全地删除旧内核?

在浏览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,只留下当前版本

我其实是在寻找这样一个命令,但我不太确定这是多么安全。 我想知道:

  • 执行此命令是否安全?
  • 这个命令如何工作? 即对这样一个大命令的小部分的解释
  • 如果此命令用于某些不同的目的,那么实现作者声称要执行的操作的正确命令是什么?

当我试图自己推断所有事情时,我变得非常困惑和沮丧。 该命令如何工作包含多个/|\*^字符很难谷歌。

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

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

  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 | xargs sudo apt-get purge自己。 故意没有-y选项,因此系统会要求您确认要对系统进行的更改。

说明

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

备择方案

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

  • 如何在更新后“清理”以前的内核?
  • 如何删除旧内核版本以清理启动菜单?
  • 从这个答案来看,以下命令似乎以更安全和更常见的方式执行相同的操作:

     sudo apt-get purge $( dpkg --list | grep -P -o "linux-image-\d\S+" | grep -v $(uname -r | grep -P -o ".+\d") ) 

你问了一步一步的解释,所以这里是:

 sudo dpkg -l 'linux-*' 

列出以包名开头的linux-

 | sed 

并将列表导入sed

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

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

 | xargs 

它会将新列表传递给xargs ,它会将其作为参数发送给

 sudo apt-get -y purge 

这将清除这些包,而不会让你改变主意。

或者更确切地说,它会将该列表发送到清除命令并将其留在那里。 是否清除了任何东西 – 而且重要的是 – 清除的内容取决于先前命令的输出。

安全吗? 在这种情况下,所有这些都取决于您发现它的post的作者如何理解正则表达式和sed语法。 这两个主题都有完整的书籍。

我开始解剖命令,阅读每个命令的man页。

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

  • seddpkg -l linux-*的输出通过管道输入sed ,其中有几个正则表达式进行解码。

  • uname -r uname打印系统信息

uname – 打印系统信息

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

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

然后将uname -r的输出用更多正则表达式传递给sed ,其输出传递给xargs

所以xargssed输出转换为包名并将它们传递给sudo apt-get purge -y ,它会自动回答所有提示的“是”:

-y, – 是, – assume-yes自动提示是; 假设“是”作为所有提示的答案并以非交互方式运行。 如果出现不良情况,例如更改保留的软件包,尝试安装未经身份validation的软件包或删除基本软件包,则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' 

这是一个截图:

在此处输入图像描述

所有旧内核版本都是iirc。