Linux使用ldd查看缺少的依赖

在Linux中经常碰到执行应用时报找不到依赖库的情况,例如CentOS7服务器版安装Puppeteer,直接执行时一定会报:

image-20200109143221841

我们可以看到报错中提示 error while loading shared libraries: libXcomposite.so.1: cannot open shared object file: No such file or directory 是缺少依赖库的意思,通常的做法是根据报错,安装这个缺少的依赖库,但是再次执行可能还会继续报缺少另外一个依赖库,再继续安装,如此往复,知道解决了所有缺少的依赖,程序才正常运行起来。这反复调试的过程,是非常耗费时间的,在我刚接触Linux的时候,一度被这种情况折腾的差点崩溃。

那么有没有一种方式,可以一次性找出到底缺少哪些依赖包,可以一次都安装上呢,直到我发现了 ldd 这个神器,这个问题才有了答案。

  • ldd ,是 list,dynamic,dependencies 的缩,也就是列出动态依赖关系的意思,简单粗暴。

其用法 : Usage: ldd [OPTION]... FILE...

我们再次观察上面那个报错,其中有提到

UnhandledPromiseRejectionWarning: Error: Failed to launch chrome! /home/devspace/nodespace/puppeteer12306/node_modules/puppeteer/.local-chromium/linux-706915/chrome-linux/chrome

这是表示在启动 chrome 的时候发生的报错,那么我们这么操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
[root@abc]# ldd /home/devspace/nodespace/puppeteer12306/node_modules/puppeteer/.local-chromium/linux-706915/chrome-linux/chrome
linux-vdso.so.1 => (0x00007ffdda9b6000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f4861a46000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f486182a000)
librt.so.1 => /lib64/librt.so.1 (0x00007f4861622000)
libX11.so.6 => /lib64/libX11.so.6 (0x00007f48612e4000)
libX11-xcb.so.1 => /lib64/libX11-xcb.so.1 (0x00007f48610e2000)
libxcb.so.1 => /lib64/libxcb.so.1 (0x00007f4860eba000)
libXcomposite.so.1 => not found
libXcursor.so.1 => not found
libXdamage.so.1 => /lib64/libXdamage.so.1 (0x00007f4860cb7000)
libXext.so.6 => /lib64/libXext.so.6 (0x00007f4860aa5000)
libXfixes.so.3 => /lib64/libXfixes.so.3 (0x00007f486089f000)
libXi.so.6 => not found
libXrender.so.1 => /lib64/libXrender.so.1 (0x00007f4860694000)
libXtst.so.6 => not found
libgobject-2.0.so.0 => /lib64/libgobject-2.0.so.0 (0x00007f4860444000)
libglib-2.0.so.0 => /lib64/libglib-2.0.so.0 (0x00007f486012e000)
libnss3.so => /lib64/libnss3.so (0x00007f485fe01000)
libnssutil3.so => /lib64/libnssutil3.so (0x00007f485fbd2000)
libsmime3.so => /lib64/libsmime3.so (0x00007f485f9ab000)
libnspr4.so => /lib64/libnspr4.so (0x00007f485f76d000)
libcups.so.2 => not found
libdbus-1.so.3 => /lib64/libdbus-1.so.3 (0x00007f485f51d000)
libXss.so.1 => not found
libgio-2.0.so.0 => /lib64/libgio-2.0.so.0 (0x00007f485f17e000)
libexpat.so.1 => /lib64/libexpat.so.1 (0x00007f485ef54000)
libXrandr.so.2 => not found
libasound.so.2 => /lib64/libasound.so.2 (0x00007f485ec54000)
libm.so.6 => /lib64/libm.so.6 (0x00007f485e952000)
libatk-1.0.so.0 => not found
libatk-bridge-2.0.so.0 => not found
libpangocairo-1.0.so.0 => not found
libpango-1.0.so.0 => not found
libcairo.so.2 => /lib64/libcairo.so.2 (0x00007f485e61b000)
libatspi.so.0 => not found
libgtk-3.so.0 => not found
libgdk-3.so.0 => not found
libgdk_pixbuf-2.0.so.0 => not found
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f485e405000)
libc.so.6 => /lib64/libc.so.6 (0x00007f485e038000)
/lib64/ld-linux-x86-64.so.2 (0x00007f486bc8d000)
libXau.so.6 => /lib64/libXau.so.6 (0x00007f485de34000)
libpcre.so.1 => /lib64/libpcre.so.1 (0x00007f485dbd2000)
libffi.so.6 => /lib64/libffi.so.6 (0x00007f485d9ca000)
libplc4.so => /lib64/libplc4.so (0x00007f485d7c5000)
libplds4.so => /lib64/libplds4.so (0x00007f485d5c1000)
libsystemd.so.0 => /lib64/libsystemd.so.0 (0x00007f485d390000)
libgmodule-2.0.so.0 => /lib64/libgmodule-2.0.so.0 (0x00007f485d18c000)
libz.so.1 => /lib64/libz.so.1 (0x00007f485cf76000)
libselinux.so.1 => /lib64/libselinux.so.1 (0x00007f485cd4f000)
libresolv.so.2 => /lib64/libresolv.so.2 (0x00007f485cb36000)
libmount.so.1 => /lib64/libmount.so.1 (0x00007f485c8f3000)
libpixman-1.so.0 => /lib64/libpixman-1.so.0 (0x00007f485c64a000)
libfontconfig.so.1 => /lib64/libfontconfig.so.1 (0x00007f485c408000)
libfreetype.so.6 => /lib64/libfreetype.so.6 (0x00007f485c149000)
libEGL.so.1 => /lib64/libEGL.so.1 (0x00007f485bf35000)
libpng15.so.15 => /lib64/libpng15.so.15 (0x00007f485bd0a000)
libxcb-shm.so.0 => /lib64/libxcb-shm.so.0 (0x00007f485bb06000)
libxcb-render.so.0 => /lib64/libxcb-render.so.0 (0x00007f485b8f8000)
libGL.so.1 => /lib64/libGL.so.1 (0x00007f485b66c000)
libcap.so.2 => /lib64/libcap.so.2 (0x00007f485b467000)
liblzma.so.5 => /lib64/liblzma.so.5 (0x00007f485b241000)
liblz4.so.1 => /lib64/liblz4.so.1 (0x00007f485b02c000)
libgcrypt.so.11 => /lib64/libgcrypt.so.11 (0x00007f485adab000)
libgpg-error.so.0 => /lib64/libgpg-error.so.0 (0x00007f485aba6000)
libdw.so.1 => /lib64/libdw.so.1 (0x00007f485a957000)
libblkid.so.1 => /lib64/libblkid.so.1 (0x00007f485a717000)
libuuid.so.1 => /lib64/libuuid.so.1 (0x00007f485a512000)
libbz2.so.1 => /lib64/libbz2.so.1 (0x00007f485a302000)
libGLdispatch.so.0 => /lib64/libGLdispatch.so.0 (0x00007f485a04c000)
libGLX.so.0 => /lib64/libGLX.so.0 (0x00007f4859e1a000)
libattr.so.1 => /lib64/libattr.so.1 (0x00007f4859c15000)
libelf.so.1 => /lib64/libelf.so.1 (0x00007f48599fd000)

可以看到列出了一大串依赖库,这些就是 chrome 运行所依赖的所有库,仔细观察会发现里面有一些带有 not found 的字样,这些就是我们需要安装的缺失依赖,安装这些依赖即可。

可以看到 chrome 以来的库还是很多的,一个一个找未安装的库还是有点不容易看,我们还可以更进一步这么操作:

image-20200109144305410

这样就只列出来了缺少的依赖,一目了然,安装即可。

补充

ldd 固然是非常好用,很多同学可能会拿着 ldd 去到处测试了(其实就是作者自己😁)。

  • ldd $(which git)
1
2
3
4
5
6
7
ldd $(which git)
linux-vdso.so.1 => (0x00007fffc15a3000)
libpcre.so.1 => /lib64/libpcre.so.1 (0x00007fa44d14a000)
libz.so.1 => /lib64/libz.so.1 (0x00007fa44cf34000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fa44cd17000)
libc.so.6 => /lib64/libc.so.6 (0x00007fa44c956000)
/lib64/ld-linux-x86-64.so.2 (0x00007fa44d3b4000)

好用,好用,好用٩(๑>◡<๑)۶

  • ldd $(which node)
1
2
3
4
5
6
7
8
9
10
ldd $(which node)
linux-vdso.so.1 => (0x00007ffd641ee000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007fa9ca09a000)
librt.so.1 => /lib64/librt.so.1 (0x00007fa9c9e92000)
libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007fa9c9b89000)
libm.so.6 => /lib64/libm.so.6 (0x00007fa9c9887000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007fa9c9671000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fa9c9454000)
libc.so.6 => /lib64/libc.so.6 (0x00007fa9c9093000)
/lib64/ld-linux-x86-64.so.2 (0x00007fa9ca2a7000)

好用,好用,好用٩(๑>◡<๑)۶

  • ldd $(which ldd) 骚操作,来查看一下自己
1
2
[root@VM_19_9_centos puppeteer12306]# ldd $(which ldd)
not a dynamic executable

咦,翻车了。。。 这是怎么回事?

直觉上我以为是权限的原因,所以 ls /usr/bin/ -al | grep ldd

image-20200109150605228

可以看到权限是没有问题的(毕竟 ldd 自身都能执行,权限问题就是蒙一下)

那到底是什么原因呢,这里需要拿出另外一个神器 file

用法:Usage: file [OPTION...] [FILE...]

这也是一个神奇的工具,参见博文 Linux下通过神器file查看文件格式信息

我们通过 file $(which ldd) 可以查看一下:

1
2
file $(which ldd)
/usr/bin/ldd: Bourne-Again shell script, ASCII text executable

可以看到 ldd 并不是一个可执行的二进制文件,而是一个可执行的脚本文件,cat 一下:

image-20200109154319212

真香大白!

到处用 file 查看的同学(估计很少有像我这么无聊的),当发现各种奇怪的问题的时候,可以使用 file 来定位一下。

文章作者: 普通程序员
文章链接: https://programmerauthor.github.io/2020/01/09/linux-tool-ldd/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 普通程序员