记录一次 ssh 远程执行 linux 程序报错问题 cannot open share object

最近遇到一个问题,同样的 C 程序,在3台不同的机器上通过 ssh -C 的方式执行,有1台机器报错,如下:


cannot open share object: libpq.so.5


初步怀疑与机器环境有关,很可能是 LD_LIBRARY_PATH 没设置,但比较奇怪的是登录到机器上执行程序不报错,ssh -C 执行,有 1 台报错,其余 2 台不报错。


经过分析,终于找到原因,记录如下:

编译C程序,一般会指定 --prefix 参数,即指定安装目录,然后编译安装,如下:
configure --prefix=/opt/app/ --enable-deubg
make

make install


使用 ldd 查看程序依赖的动态库,libpq.so.5 默认是指向源码编译出来的 libpq.so.5
ldd /opt/app/bin/agent

    libpq.so.5 => /opt/app/lib/libpq.so.5


如果把安装目录移动一下,发现 libpq.so.5 指向了新的位置,如下:
mv /opt/app /opt/soft/app
ldd /opt/soft/app/bin/agent

    libpq.so.5 => /lib64/libpq.so.5


/lib64/libpq.so.5 是系统通过 yum 或者 rpm 包安装,并不是我们源码编译出来的,如果机器上没有默认安装 libpq,就会找不到 libpq.so.5。


登录到机器上,由于设置了 LD_LIBRARY_PATH 环境变量,能够找到 /opt/soft/app/lib,而通过 ssh -C 执行程序,其非交互式的环境变量与登录上去的交互式的环境变量不同,没有设置 LD_LIBRARY_PATH 环境变量,所以找不到 /opt/soft/app/lib。此外,3台机器中有 2 台默认安装了 libpq 包,所以那 2 台能找到 /lib64/libpq.so.5,而出问题的那台机器没有安装 libpq 包,最终无法找到 libpq.so.5 报错。


总结一下导致报错的原因:

  1. 安装目录被修改过
  2. 通过 ssh -C 执行程序,LD_LIBRARY_PATH 环境变量未设置
  3. 部分主机通过 yum 或者 rpm 安装 libpq 包,而另外 1 台未安装

解决方案:
对于安装目录变过的场景,显式指定 LD_LIBRARY_PATH 环境变量即可。
export LD_LIBRARY_PATH=/opt/soft/app/lib:$LD_LIBRARY_PATH

文章评论

0条评论