查找可执行文件使用的共享库的绝对路径

Ami*_*it 5 dynamic-linking

考虑lshw作为示例程序,以下是ldd给出的内容:

$ ldd /usr/sbin/lshw    

linux-vdso.so.1 =>  (0x00007fff8bdaf000)
libresolv.so.2 => /lib64/libresolv.so.2 (0x000000360e400000)
libsqlite3.so.0 => /lib64/libsqlite3.so.0 (0x0000003631600000)
libstdc++.so.6 => /lib64/libstdc++.so.6 (0x000000360ec00000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x000000360d800000)
libc.so.6 => /lib64/libc.so.6 (0x000000360c000000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x000000360cc00000)
libdl.so.2 => /lib64/libdl.so.2 (0x000000360c800000)
libm.so.6 => /lib64/libm.so.6 (0x000000360c400000)
/lib64/ld-linux-x86-64.so.2 (0x000000360bc00000)
Run Code Online (Sandbox Code Playgroud)

如果我想找到共享库的绝对位置(并且出于明显的原因想要排除 linux-vdso.so.1),我该怎么做?在正则表达式中使用 awk 在这里似乎很脆弱。ldd有一个详细标志(-v),它会打印共享库的完整路径,但它对机器阅读不是很友好。

有没有其他方法可以解决这个问题?如果有人知道这样做的系统调用,我也可以接受。

PS:对于一些上下文,我想在chrootjail中运行这个程序,所以我需要确保共享库都是可用的。在没有所有这些戏剧性的情况下静态编译它,但这是我希望避免的路径。

更新:

我想我可能在阅读 Michael Kerrisk 的书“Linux 编程接口”时找到了更合适的东西。如果我以 方式运行程序$ LD_DEBUG=libs lshw,它会输出各种有用的信息。例如:

$ LD_DEBUG=libs lshw 
     32058:     find library=libresolv.so.2 [0]; searching
     32058:      search cache=/etc/ld.so.cache
     32058:       trying file=/lib64/libresolv.so.2
     32058:
     32058:     find library=libstdc++.so.6 [0]; searching
     32058:      search cache=/etc/ld.so.cache
     32058:       trying file=/lib64/libstdc++.so.6
     32058:
     32058:     find library=libgcc_s.so.1 [0]; searching
     32058:      search cache=/etc/ld.so.cache
     32058:       trying file=/lib64/libgcc_s.so.1
     32058:
     32058:     find library=libc.so.6 [0]; searching
     32058:      search cache=/etc/ld.so.cache
     32058:       trying file=/lib64/libc.so.6
     32058:
     32058:     find library=libm.so.6 [0]; searching
     32058:      search cache=/etc/ld.so.cache
     32058:       trying file=/lib64/libm.so.6
     32058:
     32058:
     32058:     prelink checking: ok
     32058:
     32058:     calling init: /lib64/ld-linux-x86-64.so.2
     32058:
     32058:
     32058:     calling init: /lib64/libc.so.6
     32058:
     32058:
     32058:     calling init: /lib64/libm.so.6
     32058:
     32058:
     32058:     calling init: /lib64/libgcc_s.so.1
     32058:
     32058:
     32058:     calling init: /lib64/libstdc++.so.6
     32058:
     32058:
     32058:     calling init: /lib64/libresolv.so.2


     <more output>
Run Code Online (Sandbox Code Playgroud)

我想,如果我寻找“调用 init”行,我将在开始执行程序之前拥有它正在初始化的共享库路径。

cuo*_*glm 5

您可以在不使用正则表达式的情况下尝试 awk:

ldd /bin/ls | awk 'NF == 4 {print $3}; NF == 2 {print $1}'
Run Code Online (Sandbox Code Playgroud)

输出:

/lib/x86_64-linux-gnu/libselinux.so.1
/lib/x86_64-linux-gnu/librt.so.1
/lib/x86_64-linux-gnu/libacl.so.1
/lib/x86_64-linux-gnu/libc.so.6
/lib/x86_64-linux-gnu/libdl.so.2
/lib64/ld-linux-x86-64.so.2
/lib/x86_64-linux-gnu/libpthread.so.0
/lib/x86_64-linux-gnu/libattr.so.1
Run Code Online (Sandbox Code Playgroud)