如何正确处理现代 Ubuntu 版本中的 lib-symlinks?

如何正确处理现代 Ubuntu 版本中的 lib-symlinks?

假设我遇到了一些动态链接问题。
我可能有一些本地构建的(或手动复制的)库,它们会覆盖来自 APT 的库。该库未放置到/usr/local/lib,因此很难将其与其他库区分开来。

在 Ubuntu 18.04 LTS 上,我可以运行ldd并解析其输出,例如

export EXE=/usr/bin/mc;

dpkg -S $(ldd $EXE | grep -v "=>" | awk '{print $1}') 2> /tmp/not-from-apt
dpkg -S $(ldd $EXE | grep "=>" | awk '{print $3}') 2>> /tmp/not-from-apt

然后分析/tmp/not-from-apt文件内容。对于未损坏的 18.04 LTS 系统,此文件将仅包含一行:

$ cat /tmp/not-from-apt 
dpkg-query: no path found matching pattern *linux-vdso.so.1*

并且它被视为核心库,而不是来自任何包。

但是上述方法在 Ubuntu 20.04 LTS 上会失败,此处文件/tmp/not-from-apt从第 2 行开始会包含错误的结果:

$ cat /tmp/not-from-apt 
dpkg-query: no path found matching pattern *linux-vdso.so.1*
dpkg-query: no path found matching pattern /lib/x86_64-linux-gnu/libgpm.so.2
dpkg-query: no path found matching pattern /lib/x86_64-linux-gnu/libssh2.so.1
dpkg-query: no path found matching pattern /lib/x86_64-linux-gnu/libgmodule-2.0.so.0
dpkg-query: no path found matching pattern /lib/x86_64-linux-gnu/libglib-2.0.so.0
dpkg-query: no path found matching pattern /lib/x86_64-linux-gnu/libgcrypt.so.20

我认为这是因如下所示的符号链接而发生的:

$ ls -al / | grep lib
lrwxrwxrwx   1 root    root       7 Jan 19 04:01 lib -> usr/lib
lrwxrwxrwx   1 root    root       9 Jan 19 04:01 lib32 -> usr/lib32
lrwxrwxrwx   1 root    root       9 Jan 19 04:01 lib64 -> usr/lib64
lrwxrwxrwx   1 root    root      10 Jan 19 04:01 libx32 -> usr/libx32

其实这里还有另一个问题 - 有些包/lib*的文件列表中有,而有些包没有/usr/lib*。所以这会增加额外的混乱。

我应该针对 Ubuntu 20.04 LTS 及更新版本对方法进行哪些更改才能在我的/tmp/not-from-apt文件中获得正确的行?

答案1

根据 muru 的建议,我们应该使用realpath命令。这是因为用户合并

但需要注意的是,realpath最早阶段的运行不会按预期进行。

因此我们需要添加一个额外的步骤来处理输出文件:

dpkg -S $(realpath $(grep -E "/lib.*" --only-matching /tmp/not-from-apt)) 2> /tmp/not-from-apt-final

20.04 LTS 的完整方法如下:

export EXE=/usr/bin/mc;

dpkg -S $(ldd $EXE | grep -v "=>" | awk '{print $1}') 2> /tmp/not-from-apt
dpkg -S $(ldd $EXE | grep "=>" | awk '{print $3}') 2>> /tmp/not-from-apt

dpkg -S $(realpath $(grep -E "/lib.*" --only-matching /tmp/not-from-apt)) 2> /tmp/not-from-apt-final

/tmp/not-from-apt-final如果没有错误,它将生成一个空文件。
此外,您还可以随时检查内容以/tmp/not-from-apt获取更多信息。


ldd下面是将其他系统中的输出保存为 的情况/tmp/ldd-output,因此包未在本地安装。这里需要使用apt-file search而不是 ,dpkg -S如在GitHub 要点

sudo apt-get update
sudo apt-get install apt-file
sudo apt-file update

cd /tmp
wget -c https://gist.githubusercontent.com/N0rbert/423d9b5c8718c45a699e9d3bd406ffc6/raw/2ce8e747795b74d67a00b96d840626bd95409ad3/apt-file_ldd_parse.sh
chmod +x apt-file_ldd_parse.sh
./apt-file_ldd_parse.sh /tmp/ldd-output | grep Warning

得到如下所示的结果关于 21.10 的问题

警告:已配置的存储库不包含“linux-vdso.so.1”库。
警告:已配置的存储库不包含“/usr/lib/dcaenabler/libcurl.so.4”库。
警告:已配置的存储库不包含“/usr/lib/dcaenabler/libssl.so.1.1”库。
警告:已配置的存储库不包含“/usr/lib/dcaenabler/libcrypto.so.1.1”库。
警告:已配置的存储库不包含“libldap_r-2.4.so.2”库。
警告:已配置的存储库不包含“liblber-2.4.so.2”库。

注意:linux-vdso.so.1不是问题,它是虚拟的。

相关内容