在Linux中经常碰到执行应用时报找不到依赖库的情况,例如CentOS7服务器版安装Puppeteer,直接执行时一定会报:
我们可以看到报错中提示 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] 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
以来的库还是很多的,一个一个找未安装的库还是有点不容易看,我们还可以更进一步这么操作:
这样就只列出来了缺少的依赖,一目了然,安装即可。
补充 ldd
固然是非常好用,很多同学可能会拿着 ldd
去到处测试了(其实就是作者自己😁)。
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)
好用,好用,好用٩(๑>◡<๑)۶
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] not a dynamic executable
咦,翻车了。。。 这是怎么回事?
直觉上我以为是权限的原因,所以 ls /usr/bin/ -al | grep ldd
可以看到权限是没有问题的(毕竟 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 一下:
真香大白!
到处用 file
查看的同学(估计很少有像我这么无聊的),当发现各种奇怪的问题的时候,可以使用 file 来定位一下。