记录一次 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 报错。
	
	总结一下导致报错的原因:
- 安装目录被修改过
- 通过 ssh -C 执行程序,LD_LIBRARY_PATH 环境变量未设置
- 部分主机通过 yum 或者 rpm 安装 libpq 包,而另外 1 台未安装
	解决方案:
	对于安装目录变过的场景,显式指定 LD_LIBRARY_PATH 环境变量即可。
	export LD_LIBRARY_PATH=/opt/soft/app/lib:$LD_LIBRARY_PATH
	
文章评论