安装程序打印出“unsupported distribution”,你改了一个字符串,它继续往下走,直到一分钟后以加载器错误失败。这个顺序才是值得认出的症状:第一次失败是识别检查,第二次则是兼容性边界。它们是两个不同的问题,只是恰好出现在同一个终端里。改检查只能把你从第一个问题推到第二个问题。

症状:安装程序在你的衍生版上停下

一个读取发行版名称并拒绝继续的脚本,是在告诉你它的作者没有测试过你的衍生版。这是支持声明,不是技术事实,而且往往是错的——这个包其实能正常运行。

麻烦始于权宜之计变成了方案。改一个身份文件让检查通过,然后包就会针对实际安装的运行时去加载,或者加载失败。如果在那里失败,再怎么改身份也无济于事。

所以有用的做法是先弄清安装程序问的是哪个问题,再弄清那个答案是否重要。这是两项独立的调查,而只有第二项能预测这个包能不能用。

人们称为“系统版本”的三种版本

发行版版本指的是打包好的环境。C 库版本指的是运行时的实现及其版本。编译器版本指的是工具链。聊天时人们把三者都叫“系统版本”,但在安装程序里它们并不能互换。

cat /etc/os-release
ldd --version | head -1
gcc --version | head -1
uname -m

预编译的应用程序期望的是它被链接时存在的那个运行时。在主机上换编译器不会重新链接它,更新的工具链也不会改变二进制文件所请求的加载器符号。架构又是另一回事,因为 64 位系统上的 32 位包会失败,而这个原因任何版本字符串都解释不了。

把这四项输出和报告放在一起。收集它们只要十秒,却能回答维护者本来会用邮件问你的大部分问题。

读错误,而不是读检查

第一次启动错误才是证据。关于缺少共享对象、或关于加载器无法满足的符号版本的消息,属于运行时依赖问题。而重复发行版名称的消息,不过是换了个地方的识别检查。

动态链接器的文档 说明了库的查找是如何工作的,以及加载器会在哪里搜索。改发行版标签并不会把目录加进那条搜索路径,所以第二次失败看起来和第一次毫无关系。

不要把 ldd 当作随手的第一步,用在一个下载来的可执行文件上。它自己的手册就警告说,在某些情况下它会执行该程序,而运行不受信任的安装程序正是那条警告所指的情形。

为什么改字符串没有用

伪造操作系统身份会改变机器上每个程序如何看待自己。包管理器、支持工具和其他应用读的是同一个文件,一个让某个安装程序满意的值,几个月后可能让别的东西犯糊涂。

用另一个发行版的文件替换主机库更糟。它可能弄坏无关的软件,它对包管理器不可见,而且它需要一个没人会写下来的维护计划。这些改动不能因为一个苛刻的安装程序就被合理化。

如果这个检查确实是识别缺陷,维护者可以确认并说明受支持的修正。如果它不是缺陷,受支持的路径就是为你的平台构建,而这个答案不会因为字符串被改过就改变。

写一份维护者能据以行动的报告

记录发行版和版本、架构、VPN 版本、被拒绝的确切条件,以及如果你走到那一步时的第一个运行时错误。注明你是否改过任何东西,因为来自被改动系统的报告是另一份报告。

让原始安装程序保持不动,描述检查而不是绕过它。正是这个区分让维护者能把过窄的识别规则和真正的二进制兼容边界分开,而那是两个非常不同的缺陷,需要两种非常不同的修复。

如果答复是你的平台不受支持,那也是一个可用的结果。它告诉你去找受支持的构建,而不是再花一个晚上去对付那些从来就不是问题的身份文件。

相关文章