如何显示 Linux 中可执行文件使用的所有共享库?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/50159/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 16:24:18  来源:igfitidea点击:

How to show all shared libraries used by executables in Linux?

linuxshared-libraries

提问by Alan Szlosek

I'd like to know which libraries are used by executables on my system. More specifically, I'd like to rank which libraries are used the most, along with the binaries that use them. How can I do this?

我想知道我的系统上的可执行文件使用了哪些库。更具体地说,我想对使用最多的库以及使用它们的二进制文件进行排名。我怎样才能做到这一点?

采纳答案by John Vasileff

  1. Use lddto list shared libraries for each executable.
  2. Cleanup the output
  3. Sort, compute counts, sort by count
  1. 使用ldd到列表共享为每个可执行文件库。
  2. 清理输出
  3. 排序、计算计数、按计数排序

To find the answer for all executables in the "/bin" directory:

要在“/bin”目录中找到所有可执行文件的答案:

find /bin -type f -perm /a+x -exec ldd {} \; \
| grep so \
| sed -e '/^[^\t]/ d' \
| sed -e 's/\t//' \
| sed -e 's/.*=..//' \
| sed -e 's/ (0.*)//' \
| sort \
| uniq -c \
| sort -n

Change "/bin" above to "/" to search all directories.

将上面的“/bin”更改为“/”以搜索所有目录。

Output (for just the /bin directory) will look something like this:

输出(仅用于 /bin 目录)将如下所示:

  1 /lib64/libexpat.so.0
  1 /lib64/libgcc_s.so.1
  1 /lib64/libnsl.so.1
  1 /lib64/libpcre.so.0
  1 /lib64/libproc-3.2.7.so
  1 /usr/lib64/libbeecrypt.so.6
  1 /usr/lib64/libbz2.so.1
  1 /usr/lib64/libelf.so.1
  1 /usr/lib64/libpopt.so.0
  1 /usr/lib64/librpm-4.4.so
  1 /usr/lib64/librpmdb-4.4.so
  1 /usr/lib64/librpmio-4.4.so
  1 /usr/lib64/libsqlite3.so.0
  1 /usr/lib64/libstdc++.so.6
  1 /usr/lib64/libz.so.1
  2 /lib64/libasound.so.2
  2 /lib64/libblkid.so.1
  2 /lib64/libdevmapper.so.1.02
  2 /lib64/libpam_misc.so.0
  2 /lib64/libpam.so.0
  2 /lib64/libuuid.so.1
  3 /lib64/libaudit.so.0
  3 /lib64/libcrypt.so.1
  3 /lib64/libdbus-1.so.3
  4 /lib64/libresolv.so.2
  4 /lib64/libtermcap.so.2
  5 /lib64/libacl.so.1
  5 /lib64/libattr.so.1
  5 /lib64/libcap.so.1
  6 /lib64/librt.so.1
  7 /lib64/libm.so.6
  9 /lib64/libpthread.so.0
 13 /lib64/libselinux.so.1
 13 /lib64/libsepol.so.1
 22 /lib64/libdl.so.2
 83 /lib64/ld-linux-x86-64.so.2
 83 /lib64/libc.so.6

Edit - Removed "grep -P"

编辑 - 删除了“grep -P”

回答by pilif

to learn what libraries a binary uses, use ldd

要了解二进制文件使用哪些库,请使用 ldd

ldd path/to/the/tool

You'd have to write a little shell script to get to your system-wide breakdown.

您必须编写一个小 shell 脚本才能解决系统范围内的故障。

回答by mweerden

With lddyou can get the libraries that tools use. To rank the usage of libraries for a set of tool you can use something like the following command.

有了ldd你可以得到的工具使用的库。要对一组工具的库使用情况进行排名,您可以使用类似以下命令的内容。

ldd /bin/* /usr/bin/* ... | sed -e '/^[^\t]/ d; s/^\t\(.* => \)\?\([^ ]*\) (.*//g' | sort | uniq -c

(Here sedstrips all lines that do not start with a tab and the filters out only the actual libraries. With sort | uniq -cyou get each library with a count indicating the number of times it occurred.)

(这里sed去掉所有不以选项卡开头的行,只过滤掉实际的库。sort | uniq -c每个库都有一个计数,表明它发生的次数。)

You might want to add sort -gat the end to get the libraries in order of usage.

您可能希望sort -g在最后添加以按使用顺序获取库。

Note that you probably get lines two non-library lines with the above command. One of static executables ("not a dynamic executable") and one without any library. The latter is the result of linux-gate.so.1which is not a library in your file system but one "supplied" by the kernel.

请注意,您可能会使用上述命令获得两行非库行。一种静态可执行文件(“不是动态可执行文件”),另一种没有任何库。后者的结果linux-gate.so.1不是文件系统中的库,而是内核“提供”的库。

回答by Raghwendra

On UNIX system, suppose binary (executable) name is test. Then we use the following command to list the libraries used in the test is

在 UNIX 系统上,假设二进制(可执行)名称是 test。然后我们用下面的命令列出测试中用到的库是

ldd test

回答by Fabiano Tarlao

On Linux I use:

在 Linux 上我使用:

lsof -P -T -p Application_PID

This works better than lddwhen the executable uses a non default loader

这比ldd当可执行文件使用非默认加载器时效果更好

回答by smichak

I didn't have ldd on my ARM toolchain so I used objdump:

我的 ARM 工具链上没有 ldd,所以我使用了 objdump:

$(CROSS_COMPILE)objdump -p

$(CROSS_COMPILE)objdump -p

For instance:

例如:

objdump -p /usr/bin/python:

Dynamic Section:
  NEEDED               libpthread.so.0
  NEEDED               libdl.so.2
  NEEDED               libutil.so.1
  NEEDED               libssl.so.1.0.0
  NEEDED               libcrypto.so.1.0.0
  NEEDED               libz.so.1
  NEEDED               libm.so.6
  NEEDED               libc.so.6
  INIT                 0x0000000000416a98
  FINI                 0x000000000053c058
  GNU_HASH             0x0000000000400298
  STRTAB               0x000000000040c858
  SYMTAB               0x0000000000402aa8
  STRSZ                0x0000000000006cdb
  SYMENT               0x0000000000000018
  DEBUG                0x0000000000000000
  PLTGOT               0x0000000000832fe8
  PLTRELSZ             0x0000000000002688
  PLTREL               0x0000000000000007
  JMPREL               0x0000000000414410
  RELA                 0x0000000000414398
  RELASZ               0x0000000000000078
  RELAENT              0x0000000000000018
  VERNEED              0x0000000000414258
  VERNEEDNUM           0x0000000000000008
  VERSYM               0x0000000000413534

回答by bluebadge

On OS X by default there is no ldd, objdumpor lsof. As an alternative, try otool -L:

默认情况下,在 OS X 上没有ldd,objdumplsof。作为替代方案,请尝试otool -L

$ otool -L `which openssl`
/usr/bin/openssl:
    /usr/lib/libcrypto.0.9.8.dylib (compatibility version 0.9.8, current version 0.9.8)
    /usr/lib/libssl.0.9.8.dylib (compatibility version 0.9.8, current version 0.9.8)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1213.0.0)

In this example, using which opensslfills in the fully qualified path for the given executable and current user environment.

在此示例中, usingwhich openssl填充给定可执行文件和当前用户环境的完全限定路径。

回答by kayle

Check shared library dependencies of a program executable

检查程序可执行文件的共享库依赖项

To find out what libraries a particular executable depends on, you can use ldd command. This command invokes dynamic linker to find out library dependencies of an executable.

要找出特定可执行文件所依赖的库,您可以使用 ldd 命令。此命令调用动态链接器以找出可执行文件的库依赖项。

> $ ldd /path/to/program

> $ ldd /path/to/program

Note that it is NOT recommended to run ldd with any untrusted third-party executable because some versions of ldd may directly invoke the executable to identify its library dependencies, which can be security risk.

请注意,不建议使用任何不受信任的第三方可执行文件运行 ldd,因为某些版本的 ldd 可能会直接调用可执行文件来识别其库依赖项,这可能存在安全风险。

Instead, a safer way to show library dependencies of an unknown application binary is to use the following command.

相反,显示未知应用程序二进制文件的库依赖关系的更安全方法是使用以下命令。

$ objdump -p /path/to/program | grep NEEDED

$ objdump -p /path/to/program | 需要grep

for more info

欲了解更多信息

回答by Shimon Doodkin

on ubuntu print packages related to an executable

在 ubuntu 上打印与可执行文件相关的包

ldd executable_name|awk '{print }'|xargs dpkg -S |awk -F  ":"  '{print }'

回答by Anders Domeij

I found this post very helpful as I needed to investigate dependencies from a 3rd party supplied library (32 vs 64 bit execution path(s)).

我发现这篇文章非常有帮助,因为我需要调查来自 3rd 方提供的库(32 位与 64 位执行路径)的依赖关系。

I put together a Q&D recursing bash script based on the 'readelf -d' suggestion on a RHEL 6 distro.

我根据 RHEL 6 发行版上的“readelf -d”建议整理了一个 Q&D 递归 bash 脚本。

It is very basic and will test every dependency every time even if it might have been tested before (i.e very verbose). Output is very basic too.

它非常基础,每次都会测试每个依赖项,即使之前可能已经测试过(即非常冗长)。输出也是非常基础的。

#! /bin/bash

recurse ()
# Param 1 is the nuumber of spaces that the output will be prepended with
# Param 2 full path to library
{
#Use 'readelf -d' to find dependencies
dependencies=$(readelf -d  | grep NEEDED | awk '{ print  }' | tr -d '[]')
for d in $dependencies; do
   echo "${d}"
   nm=${d##*/}
   #libstdc++ hack for the '+'-s
   nm1=${nm//"+"/"\+"}
   # /lib /lib64 /usr/lib and /usr/lib are searched
   children=$(locate ${d} | grep -E "(^/(lib|lib64|usr/lib|usr/lib64)/${nm1})")
   rc=$?
   #at least locate... didn't fail
   if [ ${rc} == "0" ] ; then
      #we have at least one dependency
      if [ ${#children[@]} -gt 0 ]; then
         #check the dependeny's dependencies
         for c in $children; do
          recurse "  " ${c}
         done
      else
         echo "no children found"
      fi
   else
      echo "locate failed for ${d}"
   fi
done
}
# Q&D -- recurse needs 2 params could/should be supplied from cmdline
recurse "" !!full path to library you want to investigate!!

redirect the output to a file and grep for 'found' or 'failed'

将输出重定向到一个文件和 grep 为“找到”或“失败”

Use and modify, at your own risk of course, as you wish.

当然,根据您的意愿使用和修改,风险自负。