此命令是否可以安全地删除旧内核?
在浏览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使用它
-
它在不问你的情况下进行更改。
apt-get -y purge
部分允许单行开始执行清除包,而无需您的确认。 如果脚本中存在任何错误,那么您可能会被搞砸 。 -
没有来源,没有作者给出。 它的来源在这里有所不同。 如果它来自经过全面测试的系统包,我们可以跟踪正在进行的测试。 从随机来源,我们不能相信它。
-
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-
开头的软件包作为名称。 -
|
(管道)将左侧命令的输出(我们称之为stdout
)stdout
到右侧命令的输入(我们称之为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-
(通常是内核)开头的软件包。 -
sed
:dpkg -l linux-*
的输出通过管道输入sed
,其中有几个正则表达式进行解码。 -
uname -r
uname
打印系统信息
uname – 打印系统信息
-r
句柄专门打印内核版本:
-r, – kernel-release打印内核版本
然后将uname -r
的输出用更多正则表达式传递给sed
,其输出传递给xargs
所以xargs
将sed
输出转换为包名并将它们传递给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。