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

Bha*_*wan 21 package-management security command-line

在网上浏览 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
Run Code Online (Sandbox Code Playgroud)

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

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

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

当我试图自己推论时,我变得非常困惑和沮丧。它包含了这是如何指挥工作众多/|\*,和^字符,这是很难为谷歌。

我正在寻找此命令的分步翻译和解释,但我无法在互联网上找到!

ger*_*ijk 28

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

  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'
Run Code Online (Sandbox Code Playgroud)

这仅仅只是输出的东西和运行与普通用户的权限。一旦您同意删除这些内核,您就可以添加 | 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] 清除(删除所有内容)给定的包(作为参数)。

备择方案

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

  • @Z9iT 这些是正则表达式。它们用于根据它们所代表的 *表达式* 查找匹配项,并且 `\1` 是执行某种通用搜索和替换的替换控件。对于删除任何包,我已经在我的回答中明确表达了自己(我的意见):使用常识。不要让脚本自动更改您的系统。验证它会做什么。总是。 (4认同)

cha*_*kes 7

你要求一步一步的解释,所以这里是:

sudo dpkg -l 'linux-*'
Run Code Online (Sandbox Code Playgroud)

列出linux-以包名开头的包

| sed
Run Code Online (Sandbox Code Playgroud)

并将列表通过管道传输到 sed

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

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

| xargs
Run Code Online (Sandbox Code Playgroud)

这会将新列表通过管道xargs传输到,然后将其作为参数发送到

sudo apt-get -y purge
Run Code Online (Sandbox Code Playgroud)

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

或者更准确地说,它将将该列表发送到清除命令中并保留它。是否清除任何东西——重要的是——究竟清除什么取决于前面命令的输出。

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


Set*_*eth 6

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

  • dpkg -l: list 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, --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'  
Run Code Online (Sandbox Code Playgroud)

这是一个屏幕截图:

在此处输入图片说明

所有旧内核版本 iirc。

  • 我现在正在尝试理解它,可能需要我们一段时间;) (2认同)