一种可能性是将您需要的辅助库加载到“私有”位置,然后更改程序的标头以搜索该位置。
模仿你的目标环境
- 在您自己的机器上安装一个虚拟机,运行与托管公司相同的 CentOS 版本。这意味着相同的 CentOS 版本和相同的 CPU 架构。(
cat /etc/*-release
应该给你一个信息;uname -a
会给你另一个。具体来说,你要确保你有一个相似/相同的 C 库版本;/lib/libc.so.?
应该是可执行的,并给你一些关于正在使用的 C 库的详细信息。)
- 在您的虚拟主机上使用 YUM 安装必要的软件包。
- 确保您的二进制可执行文件有效。
找出目标环境缺少什么
运行ldd /usr/bin/your-app
以获取它所引用的库列表。具体来说,要清理该列表: ldd /usr/bin/your-app | cut -d '(' -f 1 | cut -d '>' -f 2 | sed -e 's,[ \t],,g' | sort | uniq > my-required-libs
登录远程服务器并将文件复制过来;然后运行类似:
#!/bin/sh
$(< my-required-libs ) 中 lib 的缺失库 do if [ -f "$lib" ] then echo "OK $lib" else echo "NO $lib" echo "$lib" >> missing-libs fi完毕
复制missing-libs
回您的虚拟主机和mkdir
名为 eg 的文件夹~/my-app/lib
;然后cp $(<missing-libs) /home/myself/my-app/lib
注意,你需要在你的共享主机上创建这个确切的路径,包括用户名等等——所以如果你在共享主机上的可写目录是/home/myself
确保这个目录/home/myself
也在虚拟主机上。
更改可执行文件的 RPATH 以指向您的备用库位置
找到您的应用程序可执行文件并使用以下方法更改其标头chrpath
(您可能需要yum install chrpath
在虚拟机中这样做,因为这是一个不寻常的程序):
chrpath --list /usr/bin/your-app
如果这报告了任何现有的 RPATH,那么您需要在该 RPATH 的路径 ~/my-app/lib 前面加上一个:
- 例如,如果chrpath --list
显示/usr/lib/my-app/plugins
您可能使用/home/myself/my-app/lib:/usr/lib/my-app/plugins
. 在更常见的情况下,只需使用--replace
您已将必备库复制到的目录的名称。
chrpath --replace ~/my-app/lib /usr/bin/your-app
现在,将带有新 RPATH 的可执行文件和包含支持库的目录复制到您的共享主机。
这对于多用户共享主机设置来说都是“友好的”,这与使用chroot
监狱等其他解决方案不同。
或者,创建一个 LD_LIBRARY_PATH 包装器
如果chrpath
不适用于您的设置(例如极其严格的 SELinux 上下文),您可以跳过该chrpath
步骤,而是执行以下操作:
mv ~/my-app/bin/my-app ~/my-app/bin/my-app.real
并制作一个包装脚本,如
#!/bin/sh
export LD_LIBRARY_PATH=/home/myself/my-app/lib
exec /home/myself/my-app/bin/my-app.real
…并用这个脚本替换原始二进制文件的名称。
请注意,理论上,您可以通过这种方式替换几乎任何库,但是当库在特定位置(例如/etc
)需要数据文件或从系统位置(例如)动态调用子库时/usr/lib64
,您可能不得不使用新的重新编译它们./configure
除了最极端的情况外,他们的脚本中的路径或以可能不值得付出努力的方式编辑其源代码。
EG:以这种方式重新定位不友好的东西:libc
和可插入的身份验证模块。