Pyinstaller打包应用调用mysqlbinlog提示ZLIB_1.2.9缺失如何解决
问题解决方案
首先明确问题根因:PyInstaller 打包的可执行程序启动时,会自动将应用安装目录追加到 LD_LIBRARY_PATH 环境变量的最靠前位置,该环境变量会默认继承给 subprocess 启动的子进程,因此 mysqlbinlog 会优先加载打包目录中低版本的 libz.so.1 库,导致版本不兼容报错。
推荐解决方案
方案1:调用subprocess时重置LD_LIBRARY_PATH(兼容性最优)
无需修改打包逻辑,也不会影响主程序自身对打包库的依赖,仅修改子进程的环境变量即可:
import os import subprocess # 复制当前进程的全部环境变量 run_env = os.environ.copy() app_root = os.path.dirname(os.path.abspath(__file__)) # 过滤掉LD_LIBRARY_PATH中应用自身的库路径,保留系统默认路径 if "LD_LIBRARY_PATH" in run_env: lib_paths = run_env["LD_LIBRARY_PATH"].split(":") filtered_paths = [p for p in lib_paths if not p.startswith(app_root)] run_env["LD_LIBRARY_PATH"] = ":".join(filtered_paths) # 调用subprocess时传入修改后的环境变量 subprocess.run( command_args, check = True, shell = True, stdout = subprocess.PIPE, stderr = subprocess.PIPE, env=run_env )
如果确认 mysqlbinlog 不需要依赖任何你打包进应用目录的自定义库,也可以直接删除该环境变量:run_env.pop("LD_LIBRARY_PATH", None),操作更简单。
方案2:打包时排除libz.so.1(操作最简便)
如果测试确认你的主程序自身不需要依赖打包带的低版本 libz.so.1,可以在构建时直接指定排除该库,不需要事后手动删除:
pyinstaller myapp.py --clean --name=myapp --exclude-binaries libz.so.1
建议构建后分别在CentOS7和Ubuntu20.04环境验证主程序全部功能正常,即可长期使用该配置。
方案3:临时修改子进程的库加载优先级
可以直接在mysqlbinlog命令前拼接临时环境变量声明,强制优先加载系统库,示例如下:
command_args = "LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu/ " + command_args
该方案仅适合临时测试使用,不同系统的默认库路径不同,生产环境兼容性较差。
内容的提问来源于stack exchange,提问作者Ivan
相关产品推荐
相关产品推荐

