ldd <name>
我知道,如果我对二进制文件执行命令,/bin
或者/sbin
我可以看到它使用哪些库。我该如何做相反的事情?即对文件执行命令/lib
并查看哪些二进制文件正在使用它?
答案1
这并不完全是您所要求的,但它允许您找到使用给定库的二进制文件列表。binstats
生成有关系统中的二进制文件和库的报告,主要是为了找出哪些二进制文件缺少库,以及哪些库根本不再使用。
在调试模式下,它会留下临时文件,其中之一列出了路径上(或使用该-b
选项指定的文件夹中)的所有二进制文件以及它们使用的所有库。获得此文件后,您可以搜索您感兴趣的库以确定它的用途......
所以基本上:
binstats -d
awk '/^\// { binary=$1 }; /libtinfo.so.5/ { print binary }' etempb.00
将列出所有使用libtinfo.so.5
. (文件名可能不是etempb.00
,但希望您明白......)
这将丢失存储在不在路径上的目录中的二进制文件,例如在 中/usr/libexec
,或者在/sbin
和中/usr/sbin
(如果您不是以 运行)root
,但您可以将相关文件夹添加到该-b
选项。
答案2
OP没有澄清;但是如果你想知道哪个当前正在运行进程正在使用给定的库,lsof
这很有用,因为(使用共享库中的文件描述符),它能够列出当前使用的所有共享库以及加载它们的程序的名称。
例如,以下是我正在使用的文本编辑器所用文件的列表(删除前几列):
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
顺便说一下,并不是普遍可用的;lsof
用于大多数类 Unix 平台。
下面是一个示例脚本,它为当前运行的系统中的所有库生成报告(如果给出参数,它将与库名称进行匹配):
#!/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;
进一步阅读:
答案3
只要您坚持使用发行版提供的二进制文件,它就会通过包依赖项来跟踪这一点。
- 确定包含该库文件的包。
- 列出依赖于该库包的包。
- 列出这些包中的可执行文件。
当然,这不会告诉您有关未通过发行版打包机制安装的程序的信息。当一个包包含多个可执行文件时,这也会列出额外的可执行文件。另一方面,对于许多用途来说,包是您需要的信息,而不是可执行文件。
如何执行每个步骤取决于您的发行版使用的包管理器。这吃豆子罗塞塔有一个流行发行版上的包管理命令表。例如,在 Debian、Ubuntu、Linux Mint、elementary OS 和其他基于 dpkg/apt 的发行版上:
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
答案4
如有疑问,请使用暴力:
#!/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
浏览系统上所有 PATH 可执行文件(~ 4K)大约需要一分钟。