3

I'm running the following linux distro ...

DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=20.04
DISTRIB_CODENAME=focal
DISTRIB_DESCRIPTION="Ubuntu 20.04.2 LTS"

I went into aptitude, and it is now telling me that all 1,425 of my installed packages are to be removed because they are no longer in use. All I can think of is that I might have accidentally hit the wrong key in aptitude.

How do I properly correct this?

Thank you very much in advance.

PS: my /etc/sources.list file and /etc/sources.list.d directory have not changed.

PPS: I now realize that this isn't all of my packages, just about half of them. But they are generally standard linux packages.

PPPS: aptitude keep-all runs without generating any error message, but it doesn't fix the problem. However, if I go into the aptitude gui and hit a plus sign (+) on any of the packages, it puts me into an "examine" dialog in which I am given the option to "keep the following packages at their current version". If I select that option, the package is no longer marked as needing to be removed. However, I have more than 1,400 packages, and it will take me a long time to manually mark all of these and go through this dialog. Is there a way to make this happen for all of those packages with one, single command?

2 Answers 2

3

The dpkg database (in /var/lib/dpkg/status) stores the intended state of the package in the same line as current state as described in dpkg(1). So an installed package would have an entry similarly to this example:

# dpkg -s hello| egrep '^(Package|Status|Architecture):'
Package: hello
Status: install ok installed
Architecture: amd64

Once you use a tool to set the intention to remove it it would appear as:

# dpkg -s hello| egrep '^(Package|Status|Architecture):'
Package: hello
Status: deinstall ok installed
Architecture: amd64

With purge instead of deinstall for a to-be-purged package.

You probably selected (for deinstallation) an important package which triggered the change on others selected or a whole group of packages.

There are a few tools that can do this, among them the venerable dselect, aptitude, the lower level dpkg --set-selections or apt-mark. The latter one is easier to use but still can't be used to check what was changed (because it won't compare deinstall to installed above) and can only do one operation at a time so would be very slow on multiple fixes. dpkg --set-selections will be preffered because it can do this in one invocation.

Note that everything got a bit more complicated with multi-arch where the Architecture value has to be retrieved to distinguish a package installed twice in two architectures. Note that architecture all also works for packages without real architecture.

Here's a cancel-changes.awk script that will set the intention to be compatible with the current state: install what is installed, purge what is not and keep deinstalled what is removed (still keeping configuration files), in a format suitable for 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 } 

You should verify the output of this script before actually feeding it to dpkg --set-selections. A future release of Debian (and Ubuntu) might change the internal format.


Here's an usage example on Debian 10, to test on the victim package 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
9
  • Hum while I'm glad to have made this script, I realize I missed the point. It's probably a meta package on which depended a lot of packages that was removed (completely). So this answer probably doesn't answer the question, and since OP already fixed the problem, it would be difficult to test it on the actual problem to clarify.
    – A.B
    Apr 5, 2021 at 10:22
  • Yes, but all of what you explained is quite helpful, anyway. My understanding of apt internals has been sketchy, at best, and now you have provided very useful information to help me improve my understanding. So thank you!
    – HippoMan
    Apr 7, 2021 at 15:23
  • PS: I didn't knowingly delete any packages before this happened, but perhaps I did so without realizing it by mistyping something in aptitude. Anyway, your tool is quite useful, in case any similar work is needed in the future. And as I mentioned, I now have a better understanding of apt because of your explanations.
    – HippoMan
    Apr 7, 2021 at 15:31
  • PPS: given a list of packages (such as the 1,400+ packages that I have mentioned here), is there a way to find the package or packages which sit at the top level of the tree of dependencies for this entire list of packages taken as a whole? That would tell me what (meta-)package(s) that I might have deleted and which could then be reinstalled to possibly fix this problem.
    – HippoMan
    Apr 7, 2021 at 15:38
  • The kind of package that could inadvertantly be removed without any effect (except the autoremove effect) would be all task meta-packages. Try apt-cache search ^task- to get a partial list. Something like task-desktop or similar might end up holding a lot of packages in dependency.
    – A.B
    Apr 7, 2021 at 16:20
1

OK. I was able to work around this, although I don't know if it's an actual solution or just a "band aid" which covers up a deeper, underlying problem. Here's what I did ...

First of all, I tried to do an apt install on one of those packages which were marked for removal. It succeeded and gave me a list of the remaining 1,400+ packages, with several packages on each line of output.

I copied that list of packages into a file and pre-pended apt install on each line, and then I ran that through my shell.

This converted all those packages from "auto" to "manual".

I then ran aptitude keep-all, and now, all the packages stopped being shown as being "not in use".

I'm glad I could do this, but I'm still mystified as to how this problem could have occurred in the first place. And as I mentioned, I don't know if there is another, more basic problem with apt or aptitude on my system which still needs to be fixed.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .