昨晚我试图刻录 CD。由于对 k3b 感到厌烦并选择使用 brasero,所以我决定删除 k3b。
我输入:
sudo apt-get remove k3b
我按了两次 Tab 键,发现我的系统上有 k3b 和 k3b-data。假设没有 k3b,我的系统上就不需要 k3b-data,所以我也想删除它,所以我输入了:
sudo apt-get remove k3b*
k3b
不幸的是,我没有看就按了 Y 确认。它卸载了比和更多的软件包k3b-data
。它卸载了不符合我的k3b*
正则表达式的软件包。例如:transmission
和network-manager
。
k3b
我相当确定and之间没有空格,*
但我不知道为什么它会删除所有的内容。我对 apt-get 有什么误解吗?
答案1
您想要的命令是sudo apt-get remove '^k3b.*'
,因为:
- 您需要
.*
匹配任意字符,任意次数 - 您需要
^
匹配字符串的开头 - 您需要引用正则表达式以防止 bash 将其解释
*
为通配符
(此答案补充并总结了 qbi 和 Flimm 先前提供的信息)
答案2
正则表达式*
代表零个或任意多个。因此,您被告知apt-get
要删除包含 的任何内容, k3
后面跟着任意数量的b
,所以基本上是包含 的所有内容k3
。如果我在我的系统上尝试您的命令,它会删除 58 个包。
sudo apt-get remove -s k3b*
Package k3b is not installed, so not removed
Package k3b-data is not installed, so not removed
Package k3b-dbg is not installed, so not removed
Package libcanberra-gtk3-0 is not installed, so not removed
Package libcanberra-gtk3-0-dbg is not installed, so not removed
Package libcanberra-gtk3-dev is not installed, so not removed
…
The following packages will be REMOVED:
appmenu-gtk ardour audacity brasero brasero-cdrkit firefox-globalmenu
gconf-editor gir1.2-appindicator-0.1 gnome-applets gnome-control-center
…
0 upgraded, 2 newly installed, 58 to remove and 0 not upgraded.
答案3
改用sudo apt-get remove ^k3b
。当您安装或删除软件包时,*
通常是危险的,而且很少需要。如果您确实使用*
,则应该引用它,但这样做不是使其更安全,因为它倾向于选择比你预期更多的包,这是由它的方式apt
和apt-get
解释方式造成的,不是效果路径名扩展。
- 甚至安全使用
*
是通常是不必要的。 - 不安全用途残酷. 删除将
k3b*
删除所有包含k3
任何地方在其名称中(以及依赖于此类包的每个包)。这不是拼写错误 - 包含k3
就足够了,即使没有b
,因为b*
表示“零个或多个b
”。
当你跑步时apt
或者apt-get
使用install
、remove
或purge
操作时,每个后续参数都是第一个1解释为单个包的名称。如果存在具有该名称的包,则将对其执行操作。
如果没有这样的包,apt
将apt-get
检查参数是否包含任何常见的正则表达式 元字符2 .
,?
,+
,*
,|
,\[
,^
, 或者$
如果没有,就完成了——没有找到包。
如果它做包含任何这些字符,那么它将被视为正则表达式并进行匹配任何部分任何包名称。它不必匹配整个名称。正如其他人所说,*
在正则表达式中并不意味着与*
在 glob 中相同。?
也不一样。在正则表达式中:
apt-get(8)(man apt-get
)表示:
如果没有包与给定的表达式匹配,并且表达式包含“.”、“?”或“*”之一,则假定它是 POSIX 正则表达式,并将其应用于数据库中的所有包名称。然后安装(或删除)任何匹配项。请注意,匹配是通过子字符串完成的,因此“lo.*”匹配“how-lo”和“lowest”。如果不希望出现这种情况,请使用“^”或“$”字符固定正则表达式,或创建更具体的正则表达式。
手册页仅提到.
、?
和*
,但是它不完整,因为,,,,+
和也足以让或将模式解释为正则表达式。|
[
^
$
apt-get
apt
3
.*
尽管你可以用--匹配任意数量的任意字符不是只是*
——你只需要它出现在中间你的正则表达式。因为该模式与包名称的任何子字符串匹配,所以它在模式的末尾(或开头)是没有意义的。
手册页提到^
和$
. 这些(尤其是^
)是编写用于install
、remove
、 或中purge
的操作的安全、高效模式的关键。apt
apt-get
^
将正则表达式锚定到开始整个字符串。^k3b
选择所有名称为开始和k3b
。$
将正则表达式锚定到结尾整个字符串。k3b$
将选择所有名称为结尾和k3b
。
因此您可以使用此命令安全地删除软件包:
sudo apt-get remove ^k3b
最后,在您提到的具体情况下,您不妨自己传递这两个名称:
sudo apt-get remove k3b k3b-data
^
然后你就避免了所有这些复杂性!(虽然一旦你习惯了,锚定就很简单了。)或者使用括号扩展,你的 shell 会将其扩展为上述命令:
sudo apt-get remove k3b{,-data}
1 有两个例外:(A)一些选项(例如-f
,--purge
)可以被识别,并且 (二)出现在结尾参数,否则将被视为执行操作的包名称,可用于改变所执行的操作(例如,sudo apt install ubuntu-desktop^
安装任务而不是包,并且当^
出现在末尾时)。
2 还存在其他正则表达式元字符。例如,所有正则表达式\
方言都支持并且常用。.
、、、、、、、和恰好是 APT 开发人员决定触发解释为正则表达式的元字符(在解析为名为的确切包失败后)。?
+
*
|
[
^
$
3 验证这一点的最简单方法是使用上述选项,用这种模式模拟安装或删除-s
。例如,运行apt -s install ^virtualbox
显示sudo apt install ^virtualbox
将尝试安装包管理器所知道的每个以 开头的包virtualbox
。但是,也可以通过检查来验证此行为源代码. 检查CacheSetHelper::PackageFromRegEx
函数cacheset.cc
。
答案4
使用 .* 代替 *,并放在引号内 ' '
sudo apt-get remove 'k3b.*'