I know that if I do the command ldd <name> on a binary file in /bin or /sbin I can see which libraries it uses. How do I do the reverse? I.e. do a command on a file in /lib and see what binaries are using it?
- 111
- 1
- 7
-
Such a file could be almost anywhere... – Jeff Schaller May 28 '16 at 00:42
-
Do you mean currently-running processes? Just the binaries installed by your distribution? Or binaries anywhere on the whole system? – JigglyNaga May 28 '16 at 10:26
4 Answers
This isn't quite what you're asking for, but it will allow you to find the list of binaries using a given library. binstats generates a report on the binaries and libraries in your system, primarily to find out which binaries are missing libraries, and which libraries are no longer used at all.
In debug mode, it leaves its temporary files behind, and one of them lists all the binaries on the path (or in the folders you specify, using the -b option), with all the libraries they use. Once you have this file, you can search for the library you're interested in to determine what uses it...
So basically:
binstats -d
awk '/^\// { binary=$1 }; /libtinfo.so.5/ { print binary }' etempb.00
will list all the binaries using libtinfo.so.5. (The filename may not be etempb.00, but hopefully you get the idea...)
This will miss binaries stored in directories not on the path, e.g. in /usr/libexec, or in /sbin and /usr/sbin if you're not running as root, but you can add the relevant folders to the -b option.
- 411,918
- 54
- 1,065
- 1,164
OP did not clarify; however if you want to know which currently running processes are using given libraries, lsof is useful, because (using the file-descriptors from the shared libraries), it is able to list all shared libraries currently in use along with the names of the programs which loaded them.
For instance, here is a listing (removing the first few columns) for the files in use for the text editor I am using:
cwd DIR 8,1 4096 783366 /tmp
rtd DIR 8,1 4096 2 /
txt REG 8,1 1007808 659475 /usr/bin/vile
mem REG 8,1 22664 1189463 /usr/lib/vile/vile-txt-filt.so
mem REG 8,1 14472 1072690 /usr/lib/perl/5.14.2/auto/Tie/Hash/NamedCapture/NamedCapture.so
mem REG 8,1 26984 717426 /usr/lib/perl/5.14.2/auto/List/Util/Util.so
mem REG 8,1 18704 717420 /usr/lib/perl/5.14.2/auto/IO/IO.so
mem REG 8,1 18672 717423 /usr/lib/perl/5.14.2/auto/Fcntl/Fcntl.so
mem REG 8,1 14472 717444 /usr/lib/perl/5.14.2/auto/Cwd/Cwd.so
mem REG 8,1 47616 914637 /lib/x86_64-linux-gnu/libnss_files-2.13.so
mem REG 8,1 43560 914639 /lib/x86_64-linux-gnu/libnss_nis-2.13.so
mem REG 8,1 89056 914574 /lib/x86_64-linux-gnu/libnsl-2.13.so
mem REG 8,1 31584 914635 /lib/x86_64-linux-gnu/libnss_compat-2.13.so
mem REG 8,1 10272 714121 /usr/lib/x86_64-linux-gnu/gconv/ISO8859-1.so
mem REG 8,1 110939968 692851 /usr/lib/locale/locale-archive
mem REG 8,1 530736 914572 /lib/x86_64-linux-gnu/libm-2.13.so
mem REG 8,1 35104 914569 /lib/x86_64-linux-gnu/libcrypt-2.13.so
mem REG 8,1 131107 913941 /lib/x86_64-linux-gnu/libpthread-2.13.so
mem REG 8,1 14768 914571 /lib/x86_64-linux-gnu/libdl-2.13.so
mem REG 8,1 1607696 914566 /lib/x86_64-linux-gnu/libc-2.13.so
mem REG 8,1 1574680 717850 /usr/lib/libperl.so.5.14.2
mem REG 8,1 167952 913960 /lib/x86_64-linux-gnu/libtinfo.so.5.9
mem REG 8,1 136936 913944 /lib/x86_64-linux-gnu/ld-2.13.so
mem REG 8,1 26066 714417 /usr/lib/x86_64-linux-gnu/gconv/gconv-modules.cache
0u CHR 136,2 0t0 5 /dev/pts/2
1u CHR 136,2 0t0 5 /dev/pts/2
2u CHR 136,2 0t0 5 /dev/pts/2
3r REG 8,1 6317 1197635 /usr/share/vile/perl/capture.pm
4r REG 8,1 1875 1197632 /usr/share/vile/perl/Vile/Manual.pm
5r REG 8,1 1349 1197630 /usr/share/vile/perl/plugins.pl
6r REG 8,1 4916 1197634 /usr/share/vile/perl/hgrep.pm
7r REG 8,1 652 1197643 /usr/share/vile/perl/Visit.pm
8r REG 8,1 1680 1197625 /usr/share/vile/perl/Glob2re.pm
9r REG 8,1 3986 1197638 /usr/share/vile/perl/dirlist.pm
10r FIFO 0,8 0t0 25311 pipe
ldd, by the way, is not universally available; lsof is used on most Unix-like platforms.
Here is an example script, which generates a report for all libraries in the currently running system (if arguments are given, it matches those against the library names):
#!/usr/bin/perl -w
# $Id: lsof-libs,v 1.2 2016/05/28 13:59:33 tom Exp $
#
# Process the output from "lsof", obtaining a list of binaries by library path.
use strict;
open( FP, "lsof|" ) || do {
print STDERR "Can't open lsof: $!\n";
return;
};
my (@input) = <FP>;
close(FP);
my $program = "";
my $library = "";
my %libs;
for my $n ( 0 .. $#input ) {
my @fields = split /\s+/, $input[$n];
next if ( $#fields < 8 );
next unless ( $fields[8] =~ /^\// );
my $pathname = $fields[8];
if ( $fields[3] eq "txt" ) {
$program = $pathname;
}
elsif ( $fields[3] eq "mem" ) {
next unless ( $pathname =~ /\/lib[^\/]/ );
$library = $pathname;
my $found = ( $#ARGV < 0 );
if ( $#ARGV >= 0 ) {
for my $a ( 0 .. $#ARGV ) {
if ( $ARGV[$a] eq $library ) {
$found = 1;
last;
}
}
}
if ($found) {
my %obj;
%obj = %{ $libs{$library} } if ( $libs{$library} );
$obj{$program} = 1;
$libs{$library} = \%obj;
}
}
}
for my $lib ( sort keys %libs ) {
printf "%s\n", $lib;
my %obj = %{ $libs{$lib} };
for my $prog ( sort keys %obj ) {
printf "\t%s\n", $prog;
}
}
1;
Further reading:
- 75,040
- 9
- 171
- 268
As long as you stick to binaries provided by your distribution, it keeps track of this through package dependencies.
- Determine the package containing that library file.
- List the packages that depend on this library package.
- List executables in those packages.
Of course this won't tell you about programs that are not installed through your distribution's packaging mechanism. This will also list extra executables when a package contains more than one executable. On the flip side, for many purposes, the package is the information you need, rather than the executable.
How to perform each of these steps depends on the package manager used by your distribution. The pacman rosetta has a table of package management commands on popular distributions. For example, on Debian, Ubuntu, Linux Mint, elementary OS, and other dpkg/apt-based distributions:
dpkg -S /path/to/library.so # which package contains this library?
aptitude search "~i ~Dlibrary-package" # which installed packages depend on this library?
dpkg -L $(aptitude search -F %p "~i ~D$(dpkg -S /path/to/library.so | sed 's/:.*//')") | grep /bin
- 807,993
- 194
- 1,674
- 2,175
-
I'm wondering if this would generate a super-set of binaries? Some binaries in some packages may not depend on a given 'seed' library. – Jeff Schaller May 28 '16 at 22:10
-
@JeffSchaller Yes, it will. Good point, I should mention that. – Gilles 'SO- stop being evil' May 28 '16 at 22:18
When in doubt, use brute force:
#!/bin/bash
# $1 -- target library
IFS=:
find $PATH -maxdepth 1 -executable -type f -o -type l 2>/dev/null |
while read b; do
ldd "$b" 2>/dev/null | grep -q -F "$1" && echo "$b"
done
It takes about a minute to go through all my PATH executables (~ 4K ) on my system.
- 28,176
- 14
- 81
- 141