You are not logged in.
Hello
I would like to find and remove locally installed packages that provide same package via "Provides" directive.
For example gnu-free-fonts and noto-fonts both provide ttf-font.
So I can safely remove anyone of them as I do not need both of them.
My system may have many more such packages where I may not need both the packages.
Such redundant packages can not be found via commands like pacman -Qtdq.
So how do I find such redundant packages installed in my system which "Provide" same package? And any one of them is sufficient.
Any idea?
Thank you.
Last edited by amish (2025-06-26 07:16:32)
Offline
Search for the thing they provide using -Qs .
$ pacman -Qs ttf-font
local/ttf-dejavu 2.37+18+g9b5d1b2f-7
Font family based on the Bitstream Vera Fonts with a wider range of characters
local/ttf-jetbrains-mono-nerd 3.4.0-1 (nerd-fonts)
Patched font JetBrains Mono from nerd fonts library
$
So I can safely remove anyone of them as I do not need both of them.
pacman may be satisifed if you have only one of them, but that's not the same as not needing them.
I have /ttf-jetbrains-mono-nerd because it's the best monospace font for me.
For other font families I prefer ttf-dejavu.
Disliking systemd intensely, but not satisfied with alternatives so focusing on taming systemd.
clean chroot building not flexible enough ?
Try clean chroot manager by graysky
Offline
You did not completely understand my question.
With:
pacman -Qs PROVIDES
I must be knowing the name of PROVIDES.
But what if I do not know the name of PROVIDES?
I want to know all packages which PROVIDE same thing and are redundant.
Last edited by amish (2025-06-25 14:23:51)
Offline
Really quick and really dirty: Install pyalpm from extra and use the following python snippet:
import json
from pyalpm import Handle
handle = Handle(".", "/var/lib/pacman")
localdb = handle.get_localdb()
provides = {}
for pkg in localdb.pkgcache:
for prov in localdb.get_pkg(pkg.name).provides:
if len(prov) > 0:
if not prov in provides:
provides[prov] = []
provides[prov].append(pkg.name)
result = {}
for prov in provides:
if len(provides[prov]) > 1:
result[prov] = provides[prov]
with open('result.json', 'w') as fp:
json.dump(result, fp)
This will get you a (fugly) map of PROVIDES with a list of packagenames. Adjust to taste. Write to file. Maybe skip if localdb.get_pkg(pkg.name).provides is empty, and maybe remove all PROVIDES afterwards that have only one entry.
Take that as a starting point, not as a solution, let alone a good one.
Edited to remove empty and single-.provider keys and write to file.
Last edited by Whoracle (2025-06-25 15:29:59)
Offline
Dirtier.
Faster (I assume)
awk '/%PROVIDES%/{flag=1;next}/^$/{flag=0}flag{ printf "%s\t%s\n", FILENAME, $0}' /var/lib/pacman/local/*/desc | sed 's%/var/lib/pacman/local/\(.*\)/desc%\1%g' | sort -k2 | uniq -Df1
Edit: and wrong, after changing the field order for uniq -f1 i forgot to adjust the sort key ("-k2", now fixed)
Last edited by seth (2025-06-25 15:35:05)
Online
@seth - great that was long but good command.
Thank you very much.
I have no clue what it does but it seems to work.
However, some packages may have multiple PROVIDES, for example acl, alsa-lib etc.
grep -A2 PROVIDES /var/lib/pacman/local/*/desc | more
Does your code take care of that?
Please do check.
Thank you.
Thank you to @Whoracle too for python script.
Last edited by amish (2025-06-26 06:18:54)
Offline
Does your code take care of that?
I have no clue what it does but it seems to work.
You'll answer #1 by fixing condition #2 - don't copypaste shit you don't understand into an interactive shell.
Online
don't copypaste shit you don't understand into an interactive shell.
I dont know awk but I definitely looked at the code to make sure it does nothing I would not want it to do.
Thanks again.
Offline
awk '/%(NAME|PROVIDES)%/{flag=1;next}/^$/{flag=0}flag{ printf "%s\t%s\n", FILENAME, $0}' /var/lib/pacman/local/*/desc | sed 's%/var/lib/pacman/local/\(.*\)/desc%\1%g' | sort -k2 | uniq -Df1 | column -etN Package,Provides
Credit - @seth
This probably needs to be added in Arch Wiki for "pacman/Tips and tricks#Detecting more unneeded packages"
https://wiki.archlinux.org/title/Pacman … d_packages
And then user can decide if to keep or remove redundant packages.
Last edited by amish (2025-07-01 11:23:36)
Offline
https://www.datafix.com.au/BASHing/2020-10-21.html
awk '/%PROVIDES%/{flag=1;next}/^$/{flag=0}flag{ printf "%s\t%s\n", FILENAME, $0}' <file>
"/%PROVIDES%/" looks for "%PROVIDES%"", "{flag=1;next}" sets the flag and skips to the next line (cause we don't care about "%PROVIDES%" itself, "/^$/" looks for the next empty line, "{flag=0}flag" ends the range there, "{ printf "%s\t%s\n", FILENAME, $0}", "man printf", FILENAME is a special variable," $0" the entire line
If you skip the "uniq" part, you can see whether mulitple provisions are logged for several packages.
Edit: Please always remember to mark resolved threads by editing your initial posts subject - so others will know that there's no task left, but maybe a solution to find.
Thanks.
Last edited by seth (2025-06-26 07:12:24)
Online
If you skip the "uniq" part, you can see whether mulitple provisions are logged for several packages.
Yes I did that, I ran each command by splitting at pipe (|) and checking output.
printf, sort and uniq, I already knew what they did.
Thank you for awk part explanation.
Offline
You might also like https://bbs.archlinux.org/viewtopic.php … 5#p2237585 (operating on the desc files directly would have spared the entire locale issue w/ numeric sorting…)
Online
Using
pacman -Qi
would probably make it more complicated as then we will need to split "Provides:" line / array.
I did think of using pacman but I had not thought of operating directly on desc file.
So only assumption here is that DBPath was not changed in pacman.conf.
Last edited by amish (2025-06-26 12:47:05)
Offline
The other thread has a command to list the installed packages by size, it wasn't meant as a different implementation of the duplicate detection, but a different vector at slashing down the installation size.
Online
awk '/%(NAME|PROVIDES)%/{flag=1;next}/^$/{flag=0}flag{ printf "%s\t%s\n", FILENAME, $0}' /var/lib/pacman/local/*/desc | sed 's%/var/lib/pacman/local/\(.*\)/desc%\1%g' | sort -k2 | uniq -Df1 | column -etN Package,Provides
%NAME% should also be checked to find packages where NAME of one package matches with PROVIDES of other package.
For example:
ca-certificates has NO %PROVIDES% but it by default provides ca-certificates
And ca-certificates-utils also PROVIDES ca-certificates.
Edit: Pretty print output in table format
Last edited by amish (2025-07-01 11:28:05)
Offline