使用JSch库从Java执行Linux二进制文件时遇共享库加载错误
这个坑我踩过!你在PuTTY里运行/users/let/Infot完全正常,但用JSch的exec通道执行就报error while loading shared libraries: libgrt1.so: cannot open shared object file,核心原因是非交互式shell和交互式shell的环境变量差异。
PuTTY登录后是交互式shell,会自动加载你的shell配置文件(比如~/.bashrc、~/.profile或者/etc/profile),这些配置里大概率把libgrt1.so所在的目录加到了LD_LIBRARY_PATH环境变量里。但JSch的exec通道默认是非交互式的,不会加载这些配置,导致系统找不到依赖库。
给你几个靠谱的解决方案:
方案一:直接在命令里指定环境变量
把LD_LIBRARY_PATH直接拼在命令前面,强制指定共享库路径:// 替换成libgrt1.so实际所在的目录,比如/users/let/lib String command = "LD_LIBRARY_PATH=/path/to/your/libdir:$LD_LIBRARY_PATH /users/let/Infot"; ((ChannelExec) channel).setCommand(command);方案二:用登录shell执行命令
让bash以登录shell模式运行,这样会自动加载所有环境配置,和PuTTY登录后的环境完全一致:String command = "bash -l -c '/users/let/Infot'"; ((ChannelExec) channel).setCommand(command);如果你的默认shell是zsh,就换成
zsh -l -c '/users/let/Infot'。方案三:给二进制程序设置rpath(需要服务器权限)
如果你有权限修改服务器上的程序,可以直接给程序本身指定共享库搜索路径,这样不管环境变量如何都能找到依赖:- 先查看程序当前的rpath:
readelf -d /users/let/Infot | grep rpath - 用
patchelf工具设置rpath(需要服务器安装patchelf):patchelf --set-rpath /path/to/your/libdir /users/let/Infot
这样之后,不管用什么方式执行程序,都能自动找到
libgrt1.so了。- 先查看程序当前的rpath:
另外提一句,你代码里的setPty(true)其实不是必须的,不过如果用方案二的话保留也没问题,不影响结果。
内容的提问来源于stack exchange,提问作者YerivanLazerev

