21

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.

5 Answers5

12

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
barti_ddu
  • 1,451
8

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
VL-80
  • 4,693
Lucas
  • 181
4

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}')
vog
  • 250
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!
Meir
  • 1
0

You can use dpkg to get the packages that are installed (based on your list), store them in a variable, then remove them using either apt and/or dpkg. I just ran into this myself and it works great!

PKG_LIST="Put packages here space delimited and it will support globbing like this* "
PKG_TO_REM=$(dpkg --get-selections $PKG_INIT 2>/dev/null | awk '{print $1}')

apt-get remove --purge -y $PKG_REM dpkg --purge $PKG_REM

You can add other options to your dpkg syntax to remove packages that are "Unpacked", deal with dependencies, etc.

To test it out, try this to simulate the purge of your package list:

PKG_LIST="Put packages here space delimited and it will support globbing like this* "
PKG_TO_REM=$(dpkg --get-selections $PKG_INIT 2>/dev/null | awk '{print $1}')

dpkg --dry-run --purge $PKG_REM

CG3
  • 101