14

I have a scenario where I'd like to remove a set of packages that may or may not be installed, and I'd like apt-get to remove those that are and silently ignore those that aren't. Something like:

apt-get remove foo bar baz

which, if foo and bar were installed but baz was not, would remove foo and bar without complaining about baz. Is there a way to do this?

Things I've tried that haven't worked, with cups-dbg as my scapegoat actually-installed package to be removed:

jcp@a-boyd:~$ sudo apt-get remove -y cups-dbg bogus-package
Reading package lists... Done
Building dependency tree       
Reading state information... Done
E: Unable to locate package bogus-package

jcp@a-boyd:~$ sudo apt-get remove --ignore-missing cups-dbg bogus-package
Reading package lists... Done
Building dependency tree       
Reading state information... Done
E: Unable to locate package bogus-package

jcp@a-boyd:~$ sudo apt-get remove --fix-broken cups-dbg bogus-package
Reading package lists... Done
Building dependency tree       
Reading state information... Done
E: Unable to locate package bogus-package

I know I could do this with a shell script and some dpkg --list magic, but I'd like to avoid any complexity that's not absolutely necessary.

7

Is falling back to lower-level tool such as dpkg an option?

dpkg --remove foo bar libperl-dev
dpkg: warning: ignoring request to remove foo which isn't installed
dpkg: warning: ignoring request to remove bar which isn't installed
(Reading database ... 169132 files and directories currently installed.)
Removing libperl-dev ...

To remove packages config files use purge as below

dpkg --purge foo bar libperl-dev
  • 1
    I should have mentioned that the packages to be removed can have reverse dependencies, and I'd like those to be removed too. Apt-get is therefore much better than dpkg, but I'll accept your answer since it seems that there isn't really a better way to do this. – javawizard Dec 14 '12 at 19:22
7

I use apt-get remove --purge (aka apt-get purge) for the dependency following with a list of packages. To handle packages that don't exist I filter out packages that are not installed with the following script.

pkgToRemoveListFull="cups-dbg bogus-package"
pkgToRemoveList=""
for pkgToRemove in $(echo $pkgToRemoveListFull); do
  $(dpkg --status $pkgToRemove &> /dev/null)
  if [[ $? -eq 0 ]]; then
    pkgToRemoveList="$pkgToRemoveList $pkgToRemove"
  fi
done
apt-get --yes --purge remove $pkgToRemoveList
3

For Debian ≤ 9, it is possible to just use aptitude instead of apt-get:

sudo aptitude remove -y cups-dbg bogus-package

Aptitude prints warnings, but continues to remove your packages nevertheless:

Couldn't find any package whose name or description matched "bogus-package"
...
Removing cups-dbg ...
...

If you want to purge (delete package config files) rather than remove (keep config files), note that aptitude only purges the directly given packages, while the unused dependencies are only removed. However, you can purge all removed packages in a second step:

apt-get -y purge $(dpkg -l | grep ^rc | awk '{print $2}')
  • ok. sometimes, the bogus-package just had the wrong name. so, in case we had like 500 packages, it would be better to analyze the bogus packages too and do some tricks (for example, numbers aftre the lackage name, etc.. so, can u please give some hints on how to do this.. – nyxee Aug 15 '17 at 7:40
  • @nyxee I propose to ask this as a new question, pointing out exactly what you want to achieve. – vog Aug 16 '17 at 9:17
  • 1
    This would be a nice workaround except 1) aptitude is no longer installed by default on Ubuntu 18.04 and 2) aptitude has a pretty different (one could say weird) way to handle wildcards. – Jeff Jan 29 '19 at 14:17
  • This is not working for me on Debian 10. I see, Couldn't find any package whose name or description matched 'QUX' Unable to apply some actions, aborting – pdoherty926 Aug 30 '19 at 15:57
  • @pdoherty926 Thanks for the hint. I verified this and adjusted my answer accordingly. – vog Sep 1 '19 at 6:19
0

Another little 2-liner if anyone needs using apt:

purge_packages () {
  matchedPackages="$(echo "$(apt list --installed $* 2>/dev/null)" | grep -v '^Listing\.\.\.' | sed -s 's|[/ ].*||' | tr '\n' ' ' | sed 's/ *$//;s/^ *//')"
  [[ -n "$matchedPackages" ]] && apt purge -yq $matchedPackages
}

Explination:

apt list --installed $*         # Lists packages matched from function args, the --installed flag limits results to installed packages

2>/dev/null                     # Disregard the warning about using this command in a script

grep -v '^Listing\.\.\.'        # Remove the first line of output that says "Listing..." or "Listing... Done"

sed -s 's|[/ ].*||'             # Remove the rest of the line after the package name (I'm checking for / or space though it looks like just the slash is needed but package names will never have a space)

tr '\n' ' '                     # Put it all on one line separated by spaces

sed 's/ *$//;s/^ *//'           # Remove trailing and leading spaces from the line so it will be blank during the test next line if nothing was matched

[[ -n "$matchedPackages" ]]     # Check if any packages were matched

apt purge -yq $matchedPackages  # Purge them!
  • Welcome to SuperUser! Would you add more description to your answer as to what your script does, and how it does it? – El8dN8 Sep 5 '19 at 0:47
  • @El8dN8 Added explination – Meir Sep 5 '19 at 15:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.