2

I'm switching to CentOS from another distribution, and I'm not used to working with yum. I'd like to know if there's a way to know which installed packages have files in a directory.

For example I'd like to know which packages have files within /usr/share/applications.

Looking at what yum provides I saw there's a way to see installed packages (list installed) but even providing -q doesn't get me just the names of the packages. I saw no option to list contents of a single package however.

Is it possible? How could I do it?

2

There isn't a way to do this using yum but you can craft a rpm command that will do mostly what you want. You'll have to utilize the --queryformat option and iterate through the array of filenames using the little known option [..] in the --queryformat.

NOTE: All these features are discussed in the manual for RPM, Maximum RPM: Taking the Red Hat Package Manager to the Limit.

$ rpm -qa --queryformat '[%{NAME}: %{FILENAMES}\n]' | \
    sed 's#\(/.*/\).*$#\1#' | sort -u | grep '/usr/sbin' | head -10
abrt-addon-ccpp: /usr/sbin/
abrt-addon-pstoreoops: /usr/sbin/
abrt-addon-vmcore: /usr/sbin/
abrt-dbus: /usr/sbin/
abrt: /usr/sbin/
alsa-utils: /usr/sbin/
aoetools: /usr/sbin/
at: /usr/sbin/
authconfig: /usr/sbin/
avahi-autoipd: /usr/sbin/
...

Details

The above --queryformat iterates over the array macro %{FILENAMES} via the [...] notation, printing the name (%{NAME}) of the package they're contained in, along with their full installed path.

Example
$ rpm -q --queryformat '[%{NAME}: %{FILENAMES}\n]' fatrace
fatrace: /usr/sbin/fatrace
fatrace: /usr/sbin/power-usage-report
fatrace: /usr/share/doc/fatrace-0.5
fatrace: /usr/share/doc/fatrace-0.5/COPYING
fatrace: /usr/share/doc/fatrace-0.5/NEWS
fatrace: /usr/share/man/man1/fatrace.1.gz

With this type of output we simply need to chop off the trailing filenames from the above paths. For this I used sed. I then run the output through sort -u to condense any duplicate lines since often times, many packages will install a multitude of files into a single directory. Finally I use grep ... to find the packages which have files in a given directory. To facilitate this further you could do this:

grep $(pwd)
Example
$ pwd
/usr/sbin

$ rpm -qa --queryformat '[%{NAME}: %{FILENAMES}\n]' | \
    sed 's#\(/.*/\).*$#\1#' | sort -u | grep $(pwd)

A list of just package names

To get just the names of the packages in a unique list you can do the following:

$ rpm -qa --queryformat '[%{NAME}: %{FILENAMES}\n]' | \
    sed 's#\(/.*/\).*$#\1#' | sort -u | grep $(pwd) | \
    awk -F: '{print $1}' | head -10
abrt-addon-ccpp
abrt-addon-pstoreoops
abrt-addon-vmcore
abrt-dbus
abrt
alsa-utils
aoetools
at
authconfig
avahi-autoipd

References

  • Thanks a lot, it appeared to be rather convoluted when I first saw the command but I understand it now. I had to add a | uniq in the end not to repeat package names in your last suggestion. – Carlos Nov 21 '14 at 19:27
  • @Carlos - hmmm, the sort -u should have collapsed the list. – slm Nov 21 '14 at 20:04
  • 1
    It works fine as long as there are just one file per package in the directory, I just realized that moving the | sort -u part to after the call to awk is enough to output package names without repeated occurrences. – Carlos Nov 21 '14 at 20:56
1

I'd like to know which packages have files within /usr/share/applications

You can query for what package owns a particular file by doing a rpm -qf <absoluteFilePath>. To do an entire directory tree you can use the find command and filter the output.

For example:

[root@xxx01 ~]# find /usr/share/applications -type f -exec rpm -qf {} \; | grep -v "is not owned by any package" | sort | uniq 
firefox-31.1.0-5.el6_5.x86_64 
savui-1.0.14-13.i386 
shared-mime-info-0.70-4.el6.x86_64 
[root@xxx01 ~]#

I saw no option to list contents of a single package however.

This is a slightly different option with rpm. For example to list what files are in the firefox package:

[root@xxx01 ~]# rpm -ql firefox
/usr/bin/firefox
/usr/lib64/firefox
/usr/lib64/firefox/LICENSE
/usr/lib64/firefox/application.ini
/usr/lib64/firefox/browser/blocklist.xml
/usr/lib64/firefox/browser/chrome
/usr/lib64/firefox/browser/chrome.manifest
/usr/lib64/firefox/browser/chrome/icons
/usr/lib64/firefox/browser/chrome/icons/default
/usr/lib64/firefox/browser/chrome/icons/default/default16.png
/usr/lib64/firefox/browser/chrome/icons/default/default32.png
/usr/lib64/firefox/browser/chrome/icons/default/default48.png
/usr/lib64/firefox/browser/components
/usr/lib64/firefox/browser/components/components.manifest
/usr/lib64/firefox/browser/components/libbrowsercomps.so
/usr/lib64/firefox/browser/defaults/preferences
/usr/lib64/firefox/browser/extensions
/usr/lib64/firefox/browser/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}
/usr/lib64/firefox/browser/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/icon.png
/usr/lib64/firefox/browser/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/install.rdf
/usr/lib64/firefox/browser/icons
/usr/lib64/firefox/browser/icons/mozicon128.png
... snip ...
  • Thanks that was enlightening, I though only yum was used for packaging but it appears to be a frontend mostly. Your solution to the problem relies on the files being present in the system: if you delete the files of a package it wouldn't tell you that the package has files in that directory. – Carlos Nov 21 '14 at 19:29
  • Ah well you used the present tense in your post so I had assumed you were trying to assess the impact of some operation or something. Either way, there you go. – Bratchley Nov 21 '14 at 21:38
0

To see what package provides a particular file or directory you can use yum provides <file>:

$ yum provides /usr/share/applications/*
Loaded plugins: fastestmirror, langpacks
Loading mirror speeds from cached hostfile
 * fedora: mirrors.ircam.fr
 * rpmfusion-free-rawhide: mirrors.coreix.net
 * rpmfusion-nonfree-rawhide: mirrors.coreix.net
 * updates: ftp.uni-koeln.de
abrt-gui-2.3.0-3.fc21.x86_64 : abrt's gui
Repo        : fedora
Matched from:
Filename    : /usr/share/applications/abrt-applet.desktop



alacarte-3.11.91-2.fc21.noarch : Menu editor for the GNOME desktop
Repo        : fedora
Matched from:
Filename    : /usr/share/applications/alacarte.desktop

and it goes on and on. Pipe it to less to read it.

To list the files in a package, simply use rpm -ql <package>

$ rpm -ql less
/etc/profile.d/less.csh
/etc/profile.d/less.sh
/usr/bin/less
/usr/bin/lessecho
/usr/bin/lesskey
/usr/bin/lesspipe.sh
/usr/share/licenses/less
/usr/share/licenses/less/LICENSE
/usr/share/man/man1/less.1.gz
/usr/share/man/man1/lessecho.1.gz
/usr/share/man/man1/lesskey.1.gz
  • Thanks for the answer, although whatprovides wouldn't be enough if the files were non present (e.g. if they were deleted). Thanks for the rpm command as well, I was just using yum. – Carlos Nov 21 '14 at 19:35
  • I beg to differ - yum provides | whatprovides even works to find a package for a known, but uninstalled, file/directory. For example, yum provides /usr/share/doc/lshw will show that this is part of the lshw package even if it hasn't ever been installed. – garethTheRed Nov 21 '14 at 19:58
0

The answer slm is almost correct, maybe it's outdated. The best script I have is the following:

rpm -qa --queryformat '[%{=NAME}: %{FILENAMES}\n]' | grep ' /var' |  cut -d: -f 1 | uniq

Notices that the meat of this is almost like the one above, the '=' make the NAME an iterator also.

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.