24

Since the installation, I have added not too few PPAs to my 15.04 system because I wanted a specific application. But sometimes I have removed that package later again, because it did not work, was not what I really wanted, or just because I don't need it any more. I don't know if that makes a difference, but some repositories were installed with add-apt-repository while others just came by a command that just created the file in /etc/apt/sources.list.d/ manually.

Now how can I check whether I have any packages from a PPA installed and if not, remove it from my software sources? This procedure should automatically work through all PPAs.

Byte Commander
  • 110,523

3 Answers3

32

Here is a script. Without a parameter, the script lists some infos. With --delete, the list files will be removed, if no packages are installed.

#!/usr/bin/env bash
for f in /etc/apt/sources.list.d/*.list; do
    grep -Po "(?<=^deb\s).*?(?=#|$)" "$f" | while read -r ENTRY ; do
    echo "ENTRY: $ENTRY"

# Sanitize entry line by removing stuff between square brackets
ENTRY=$(echo &quot;$ENTRY&quot; | sed 's/\[.*\] //')

    HOST=$(cut -d/ -f3 &lt;&lt;&lt; &quot;$ENTRY&quot;)

    if [ &quot;ppa.launchpad.net&quot; = &quot;$HOST&quot; ]; then
      USER=$(cut -d/ -f4 &lt;&lt;&lt; &quot;$ENTRY&quot;)
      PPA=$(cut -d/ -f5 &lt;&lt;&lt; &quot;$ENTRY&quot;)
      packageCount=$(sed -e '/^Package:/!d' -e 's/Package: \(.*\)$/\1/g' /var/lib/apt/lists/*&quot;$USER&quot;*&quot;$PPA&quot;*Packages | xargs dpkg -l 2&gt;/dev/null | grep -c '^ii')
      echo &quot;PPA: ppa:$USER/$PPA&quot;
      echo &quot;FILENAME: $f&quot;
      echo &quot;$packageCount package(s) installed&quot;
      if [ &quot;$packageCount&quot; -eq 0 ] &amp;&amp; [ &quot;$1&quot; == &quot;--delete&quot; ]; then
        sudo rm &quot;$f&quot; &amp;&amp; echo &quot;$f deleted&quot;
      fi
      echo
    else 
      USER=$(cut -d/ -f3 &lt;&lt;&lt; &quot;$ENTRY&quot;)
      PPA=$(cut -d/ -f4 &lt;&lt;&lt; &quot;$ENTRY&quot;)
      packageCount=$(sed -e '/^Package:/!d' -e 's/Package: \(.*\)$/\1/g' /var/lib/apt/lists/*&quot;$USER&quot;*Packages | xargs dpkg -l 2&gt;/dev/null | grep -c '^ii')
      echo &quot;REPOSITORY: $USER/$PPA&quot;
      echo &quot;FILENAME: $f&quot;
      echo &quot;$packageCount package(s) installed&quot;
      if [ &quot;$packageCount&quot; -eq 0 ] &amp;&amp; [ &quot;$1&quot; == &quot;--delete&quot; ]; then
        sudo rm &quot;$f&quot; &amp;&amp; echo &quot;$f deleted&quot; 
      fi
      echo
    fi
done

done

Copy the code above in a new file, e.g.:

mkdir -p ~/bin
nano ~/bin/checkPPAs

Make the script executable

chmod +x ~/bin/checkPPAs

And run it with

~/bin/checkPPAs

to list all repositories and the number of installed packages.

Start the script with

~/bin/checkPPAs --delete

to remove the list files.


Sample output on my system

ENTRY: http://ppa.launchpad.net/webupd8team/y-ppa-manager/ubuntu vivid main
PPA: ppa:webupd8team/y-ppa-manager
FILENAME: /etc/apt/sources.list.d/webupd8team-ubuntu-y-ppa-manager-vivid.list
3 package(s) installed

ENTRY: http://ppa.launchpad.net/nilarimogard/webupd8/ubuntu vivid main PPA: ppa:nilarimogard/webupd8 FILENAME: /etc/apt/sources.list.d/nilarimogard-ubuntu-webupd8-vivid.list 5 package(s) installed

ENTRY: http://ppa.launchpad.net/obsproject/obs-studio/ubuntu vivid main PPA: ppa:obsproject/obs-studio FILENAME: /etc/apt/sources.list.d/obsproject-ubuntu-obs-studio-vivid.list 1 package(s) installed

ENTRY: http://archive.getdeb.net/ubuntu vivid-getdeb apps REPOSITORY: archive.getdeb.net/ubuntu vivid-getdeb apps FILENAME: /etc/apt/sources.list.d/getdeb.list 7 package(s) installed

ENTRY: http://ppa.launchpad.net/psi-plus/ppa/ubuntu vivid main PPA: ppa:psi-plus/ppa FILENAME: /etc/apt/sources.list.d/psi-plus-ubuntu-ppa-vivid.list 15 package(s) installed

ENTRY: http://ppa.launchpad.net/libreoffice/ppa/ubuntu vivid main PPA: ppa:libreoffice/ppa FILENAME: /etc/apt/sources.list.d/libreoffice-ubuntu-ppa-vivid.list 24 package(s) installed

ENTRY: https://deb.nodesource.com/node_0.12 vivid main REPOSITORY: deb.nodesource.com/node_0.12 vivid main FILENAME: /etc/apt/sources.list.d/nodesource.list 1 package(s) installed

ENTRY: http://dl.google.com/linux/chrome/deb/ stable main REPOSITORY: dl.google.com/linux FILENAME: /etc/apt/sources.list.d/google-chrome.list 2 package(s) installed

ENTRY: http://ppa.launchpad.net/gnome3-team/gnome3/ubuntu vivid main PPA: ppa:gnome3-team/gnome3 FILENAME: /etc/apt/sources.list.d/gnome3-team-ubuntu-gnome3-vivid.list 273 package(s) installed

ENTRY: http://ppa.launchpad.net/noobslab/apps/ubuntu vivid main PPA: ppa:noobslab/apps FILENAME: /etc/apt/sources.list.d/noobslab-ubuntu-apps-vivid.list 0 package(s) installed

ENTRY: http://ppa.launchpad.net/ubuntuhandbook1/corebird/ubuntu vivid main PPA: ppa:ubuntuhandbook1/corebird FILENAME: /etc/apt/sources.list.d/ubuntuhandbook1-ubuntu-corebird-vivid.list 1 package(s) installed

ENTRY: http://ppa.launchpad.net/webupd8team/unstable/ubuntu vivid main PPA: ppa:webupd8team/unstable FILENAME: /etc/apt/sources.list.d/webupd8team-ubuntu-unstable-vivid.list 1 package(s) installed

ENTRY: http://download.mono-project.com/repo/debian wheezy main REPOSITORY: download.mono-project.com/repo FILENAME: /etc/apt/sources.list.d/mono-xamarin.list 166 package(s) installed

ENTRY: http://ppa.launchpad.net/otto-kesselgulasch/gimp-edge/ubuntu vivid main PPA: ppa:otto-kesselgulasch/gimp-edge FILENAME: /etc/apt/sources.list.d/otto-kesselgulasch-ubuntu-gimp-edge-vivid.list 5 package(s) installed

ENTRY: http://ppa.launchpad.net/numix/ppa/ubuntu vivid main PPA: ppa:numix/ppa FILENAME: /etc/apt/sources.list.d/numix-ubuntu-ppa-vivid.list 3 package(s) installed

ENTRY: http://ppa.launchpad.net/webupd8team/atom/ubuntu vivid main PPA: ppa:webupd8team/atom FILENAME: /etc/apt/sources.list.d/webupd8team-ubuntu-atom-vivid.list 1 package(s) installed

ENTRY: https://packages.graylog2.org/repo/debian/ trusty 1.0 REPOSITORY: packages.graylog2.org/repo FILENAME: /etc/apt/sources.list.d/graylog.list 3 package(s) installed

ENTRY: http://ppa.launchpad.net/ubuntu-mate-dev/ppa/ubuntu vivid main PPA: ppa:ubuntu-mate-dev/ppa FILENAME: /etc/apt/sources.list.d/ubuntu-mate-dev-ubuntu-ppa-vivid.list 0 package(s) installed

ENTRY: http://ppa.launchpad.net/gnome3-team/gnome3-staging/ubuntu vivid main PPA: ppa:gnome3-team/gnome3-staging FILENAME: /etc/apt/sources.list.d/gnome3-team-ubuntu-gnome3-staging-vivid.list 268 package(s) installed

ENTRY: http://debian.koha-community.org/koha stable main REPOSITORY: debian.koha-community.org/koha stable main FILENAME: /etc/apt/sources.list.d/koha.list 0 package(s) installed

ENTRY: http://ppa.launchpad.net/pgavin/ghdl/ubuntu trusty main PPA: ppa:pgavin/ghdl FILENAME: /etc/apt/sources.list.d/pgavin-ubuntu-ghdl-vivid.list 0 package(s) installed

ENTRY: http://ppa.launchpad.net/ubuntu-mate-dev/vivid-mate/ubuntu vivid main PPA: ppa:ubuntu-mate-dev/vivid-mate FILENAME: /etc/apt/sources.list.d/ubuntu-mate-dev-ubuntu-vivid-mate-vivid.list 3 package(s) installed

ENTRY: http://ppa.launchpad.net/webupd8team/sublime-text-3/ubuntu vivid main PPA: ppa:webupd8team/sublime-text-3 FILENAME: /etc/apt/sources.list.d/webupd8team-ubuntu-sublime-text-3-vivid.list 1 package(s) installed

ENTRY: http://ppa.launchpad.net/webupd8team/java/ubuntu vivid main PPA: ppa:webupd8team/java FILENAME: /etc/apt/sources.list.d/webupd8team-ubuntu-java-vivid.list 1 package(s) installed

ENTRY: http://dl.google.com/linux/chrome/deb/ stable main REPOSITORY: dl.google.com/linux FILENAME: /etc/apt/sources.list.d/google.list 2 package(s) installed

ENTRY: http://dl.google.com/linux/chrome/deb/ stable main REPOSITORY: dl.google.com/linux FILENAME: /etc/apt/sources.list.d/google-chrome-beta.list 2 package(s) installed

darnir
  • 262
A.B.
  • 92,275
  • Why do you think removing them is a bad idea? And how would you preferably remove it? add-apt-repository --remove? Or manually rm the ???.list file? What about GPG keys used by this PPA, will they also be removed if I use add-apt-repository --remove? – Byte Commander Sep 17 '15 at 08:19
  • If no package is installed, then the file can be safely deleted. I will be adding. Remove the key is a bit more complicated. – A.B. Sep 17 '15 at 08:42
  • I have updated my script. – A.B. Sep 17 '15 at 08:46
  • Start it again, one rm command had an echo – A.B. Sep 17 '15 at 08:49
  • /home/yoesoff/removeppa.sh: 4: /home/yoesoff/removeppa.sh: Syntax error: redirection unexpected – Yusuf Ibrahim Dec 24 '19 at 06:35
  • This is awesome! Is there also a way to identify which one has a missing GPG key and hence causing slowdown with each new call of add-apt-repository ppa? In such a case there usually is an error: Error: retrieving gpg key timed out. – matt525252 Apr 07 '20 at 07:05
  • It's not clear what you mean by "the list files". From the code I can clarify that it will only remove all that have 0 packages installed, regardless if it's a ppa or not, but it's not clear in your wording – Madacol Jul 22 '20 at 01:27
  • Please note that the script will not parse entries with an URL without a path correctly. For example my Spotify PPA lists: deb http://repository.spotify.com stable non-free. I have Spotify installed, but the script does not detect this correctly. – Jurrie Aug 12 '20 at 19:21
  • 1
    Wait. This reads the list files and iterates over each entry. So if any of the entries has 0 packages installed it deletes the entire file? If so, this is horribly unsafe to use. Am I missing something? – timuçin Dec 13 '22 at 09:46
  • 1
    @timuçin I see your proposed edit to the answer, but it changes it substantially enough that I think you should write up a separate answer (with credit and correction to this one) detailing your concerns and solution. If someone else can review and confirm your edit, then great, but I think it's more likely to get traction as a separate answer. – NotTheDr01ds Dec 19 '22 at 04:11
  • @A.B. I skipped reviewing this suggested edit but I'd like you to take a look at it anyway in case it's a good one. – karel Feb 07 '23 at 08:03
7

I don't know of an automatic way, but this method is fairly quick:

  1. Start synaptic package manager and input your password when prompted

  2. In the left column toward the bottom, click on Origin

All the ppas on your system will now be listed at the top of the left column. You can click down the list and see if any software is installed from each. (if there is, there will be a green box by the package name in the right column). If there are many packages from the ppa (too many to see on the screen at once), you can click on the S at the top of the right column to sort them by status.

NOTE: If you have any unused ppas:

  1. Click Settings in the top menu
  2. Then Repositories
  3. Software and Updates window will be displayed.
  4. From this window you can remove the unused ppas from the Other Software tab.
muru
  • 207,970
  • He asked how to detect unused PPAs. There are already a zillion directions about how to delete a PPA via Software Update. – Joe C Sep 03 '19 at 14:18
  • @JoeC I'm not sure what you are complaining about or why you downvoted my answer. It may not be the best way, but I do show how to detect unused PPAs. – Organic Marble Sep 03 '19 at 15:03
2

After seeing the accepted answer having a crucial error, I had to fix it and post it here.

A.B's answer iterates over the entries in each list file and if ANY of the entries in that file has 0 packages installed on the system, regardless of how many entries have packages, it removes the entire file.

It also completely disregards any entry that doesn't match a predefined format. It will not take them into account.

Also the script works with the entries matched. It leaves the empty files untouched.

So I fixed the script like so:

#!/usr/bin/env bash
for f in /etc/apt/sources.list.d/*.list; do
    fileTotal=0
    echo "FILENAME: $f"

while read -r ENTRY ; do
    echo &quot;ENTRY: $ENTRY&quot;

    # Sanitize entry line by removing stuff between square brackets
    ENTRY=$(echo &quot;$ENTRY&quot; | sed 's/\[.*\] //')

    HOST=$(cut -d/ -f3 &lt;&lt;&lt; &quot;$ENTRY&quot;)

    if [ &quot;ppa.launchpad.net&quot; = &quot;$HOST&quot; ]; then
      USER=$(cut -d/ -f4 &lt;&lt;&lt; &quot;$ENTRY&quot;)
      PPA=$(cut -d/ -f5 &lt;&lt;&lt; &quot;$ENTRY&quot;)
      packageCount=$(awk '$1==&quot;Package:&quot; {if (a[$2]++ == 0) {system(&quot;dpkg -l &quot;$2)}}' /var/lib/apt/lists/*&quot;$USER&quot;*&quot;$PPA&quot;*Packages 2&gt;/dev/null | awk '/^ii/' | wc -l)
    else 
      USER=$(cut -d/ -f3 &lt;&lt;&lt; &quot;$ENTRY&quot;)
      PPA=$(cut -d/ -f4 &lt;&lt;&lt; &quot;$ENTRY&quot;)
      packageCount=$(awk '$1==&quot;Package:&quot; {if (a[$2]++ == 0) {system(&quot;dpkg -l &quot;$2)}}' /var/lib/apt/lists/*&quot;$USER&quot;*Packages 2&gt;/dev/null | awk '/^ii/' | wc -l)
    fi

    ((fileTotal+=packageCount))
    printf '\t%s\n' &quot;REPOSITORY: $USER/$PPA&quot;
    printf '\t%s\n' &quot;$packageCount package(s) installed&quot;
    echo
done &lt; &lt;(grep -Po &quot;(?&lt;=^deb\s).*?(?=#|$)&quot; &quot;$f&quot;)

unrecognizedCount=$(grep -Pv "(?=^deb\s)|(?=^#).*" "$f" | grep -Pc "[^\s]")

unrecognizedCount=0
while read -r ENTRY ; do
    ((unrecognizedCount++))
    printf '\t%s\n' &quot;Unrecognized entry: $ENTRY&quot;
done &lt; &lt;(grep -Pv &quot;(?=^deb\s)|(?=^#).*&quot; &quot;$f&quot; | grep -P &quot;[^\s]&quot;)

echo &quot;$fileTotal packages installed&quot;
echo &quot;$unrecognizedCount entries unrecognized&quot;

if [ &quot;$fileTotal&quot; -eq 0 ] &amp;&amp; [ &quot;$unrecognizedCount&quot; -eq 0 ]; then
  if [ &quot;$1&quot; == &quot;--delete&quot; ]; then
      sudo rm &quot;$f&quot;
      sudo rm &quot;$f&quot;.*
      echo &quot;$f deleted&quot;
  else
      echo &quot;Deletable&quot;
  fi
fi

echo &quot;----------------------------&quot;

done

The usage is exactly the same except --delete option only deletes a file if there's no entry with any installed packages and no unrecognized entries. Blank and commented lines don't count as entries.

Even having considered everything I can, this is still not tested, safe script to run with sudo privileges. Please backup everything in the /etc/apt/sources.list.d directory.

timuçin
  • 123
  • 2
    @timuçin Lol - You can't win on this one, can you? I saw your edit, but I suggested it should be it's own answer. – NotTheDr01ds Dec 19 '22 at 21:14
  • @muru I saw timuçin's edit but I passed on it, as I felt that (a) it changed the original post by too much for comfort, and (b) I didn't have the ability (or time) to confirm it myself. However, it appears that ultimately it was rejected by two other reviewers. I'd be curious what you think after looking at the edit. Should we push for approval of the change to the existing answer, or leave this as a new answer? – NotTheDr01ds Dec 19 '22 at 21:19