我正在运行以下 Linux 发行版...
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=20.04
DISTRIB_CODENAME=focal
DISTRIB_DESCRIPTION="Ubuntu 20.04.2 LTS"
我进入aptitude
,它现在告诉我,我安装的所有 1,425 个软件包都将被删除,因为它们不再使用。我所能想到的就是我可能不小心按错了键aptitude
。
我该如何正确纠正这个问题?
预先非常感谢您。
聚苯乙烯:我的/etc/sources.list
文件和/etc/sources.list.d
目录没有改变。
聚苯硫醚:我现在意识到这不是我的全部包裹,只是其中的一半。但它们一般都是标准的linux 软件包。
购买力平价:aptitude keep-all
运行时不会生成任何错误消息,但它不能解决问题。但是,如果我进入 GUIaptitude
并在任何软件包上点击加号 ( +
),它会将我带入“检查”对话框,在该对话框中我可以选择“将以下软件包保留为其当前版本”。如果我选择该选项,该包将不再被标记为需要删除。但是,我有超过 1,400 个包,我需要很长时间才能手动标记所有这些包并浏览此对话框。有没有一种方法可以通过一个命令让所有这些包都发生这种情况?
答案1
dpkg 数据库(在/var/lib/dpkg/status
)存储故意的包的状态在同一行当前的状态如所述dpkg(1)
。因此,已安装的包将具有与此示例类似的条目:
# dpkg -s hello| egrep '^(Package|Status|Architecture):'
Package: hello
Status: install ok installed
Architecture: amd64
一旦您使用工具设置删除它的意图,它将显示为:
# dpkg -s hello| egrep '^(Package|Status|Architecture):'
Package: hello
Status: deinstall ok installed
Architecture: amd64
withpurge
而不是用于deinstall
要清除的包。
您可能选择(用于卸载)一个重要的软件包,该软件包触发了对其他选定软件包或整个软件包组的更改。
有一些工具可以做到这一点,其中包括古老的dselect
、aptitude
较低级别dpkg --set-selections
的或apt-mark
。后一种更容易使用,但仍然不能用于检查更改的内容(因为它不会deinstall
与installed
上面的进行比较),并且一次只能执行一项操作,因此在多次修复时会非常慢。dpkg --set-selections
将是首选,因为它可以在一次调用中完成此操作。
请注意,对于多架构,一切都变得有点复杂,Architecture
必须检索值以区分在两种架构中安装了两次的包。请注意,架构all
也适用于没有实际架构的包。
这是一个cancel-changes.awk
脚本,它将设置与当前状态兼容的意图:以适合dpkg --set-selections
.
#!/usr/bin/awk -f
/^Package:/ { package=$2; newintent="none" }
/^Status: (purge|deinstall) ok installed$/ { newintent="install" }
/^Status: install ok config-files$/ { newintent="deinstall" }
/^Status: install ok not-installed$/ { newintent="purge" }
/^Architecture:/ { package=package ":" $2 }
/^$/ && newintent != "none" { print package, newintent }
您应该在实际将脚本提供给 之前验证该脚本的输出dpkg --set-selections
。 Debian(和 Ubuntu)的未来版本可能会改变内部格式。
这是 Debian 10 上的使用示例,用于测试受害者软件包hello
。
# apt-get install hello
[...]
# apt-mark remove hello
Selected hello for removal.
# dpkg -l hello
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name Version Architecture Description
+++-==============-============-============-==================================
ri hello 2.10-2 amd64 example package based on GNU hello
# cancel-changes.awk < /var/lib/dpkg/status
hello:amd64 install
# cancel-changes.awk < /var/lib/dpkg/status | dpkg --set-selections
# dpkg -l hello
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name Version Architecture Description
+++-==============-============-============-==================================
ii hello 2.10-2 amd64 example package based on GNU hello
答案2
好的。我能够解决这个问题,尽管我不知道这是否是一个实际的解决方案,或者只是一个掩盖更深层次、根本问题的“创可贴”。这就是我所做的......
首先,我尝试apt install
对那些标记为删除的软件包之一进行操作。它成功了,并为我提供了剩余 1,400 多个包的列表,每行输出上都有几个包。
我将该包列表复制到一个文件中,并在每一行前面加上前缀apt install
,然后通过 shell 运行它。
这将所有这些包从“自动”转换为“手动”。
然后我运行了aptitude keep-all
,现在,所有软件包都不再显示为“未使用”。
我很高兴我能做到这一点,但我仍然对这个问题最初是如何发生的感到困惑。正如我所提到的,我不知道我的系统是否还有另一个更基本的问题apt
需要aptitude
修复。