![如何正确处理现代 Ubuntu 版本中的 lib-symlinks?](https://linux22.com/image/1180213/%E5%A6%82%E4%BD%95%E6%AD%A3%E7%A1%AE%E5%A4%84%E7%90%86%E7%8E%B0%E4%BB%A3%20Ubuntu%20%E7%89%88%E6%9C%AC%E4%B8%AD%E7%9A%84%20lib-symlinks%EF%BC%9F.png)
假设我遇到了一些动态链接问题。
我可能有一些本地构建的(或手动复制的)库,它们会覆盖来自 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
不是问题,它是虚拟的。