问题描述
在 ubuntu 16.04 上使用 pyinstaller 创建了一个可执行文件,并尝试在 SuSe 12 SP4 上运行它会在代码的特定部分出现错误。 代码是这样工作的:
该可执行文件已在 ubuntu 机器上成功创建并成功运行,没有发现任何问题,但是当我在 SuSe12 SP4 上使用此可执行文件时,它会启动,但是当它到达运行 bash 脚本的代码时,它会引发以下错误:
sh: /tmp/_MEI369vhy/libreadline.so.6: no version information available (required by sh)
我真的厌倦了寻找解决方案,到目前为止已经完成了以下工作:
- 尝试了 --onefile 和 --onedir,没有区别
- 尝试在 SuSe12 sp4 本身上创建可执行文件,但它引发了关于未找到子进程的不同错误
- 尝试在 Suse 上找到 libreadline.so,但没有运气
- 尝试在 ubuntu 14 上创建环境,但依赖项错误太多
我终于没有建议了,可以在这里使用一些帮助。如果可以,请提供帮助。
环境
Python 2.7.12
Ubuntu 16.04
SuSe12 SP4
pyinstaller 3.6
P.S.如果我创建了适当的构建环境,那么作为原始 Python 代码的代码在 SuSe 12 SP4 上可以完美运行
解决方法
所以,我终于在 Rokm 的帮助下解决了这个问题。上面的警告消息没有引起任何问题,但这是由于环境变量没有传递给子进程。 为了解决这个问题,我简单地做了以下事情:
###Add the following code to your existing code
env = dict(os.environ) # make a copy of the environment
lp_key = 'LD_LIBRARY_PATH' # for GNU/Linux and *BSD.
lp_orig = env.get(lp_key + '_ORIG')
if lp_orig is not None:
env[lp_key] = lp_orig # restore the original,unmodified value
else:
# This happens when LD_LIBRARY_PATH was not set.
# Remove the env var as a last resort:
env.pop(lp_key,None)
接下来,将 env 变量添加到子进程 Popen 命令。这是完整的代码供参考。此代码将为您提供命令的输出并返回代码,即命令的退出代码。此外,您不必使用任何 shelix 或任何其他东西来运行它,简单的 .strip() 命令将为您完成。希望你们觉得它有用,享受。 !!
from subprocess import Popen,PIPE,STDOUT
env = dict(os.environ) # make a copy of the environment
lp_key = 'LD_LIBRARY_PATH' # for GNU/Linux and *BSD.
lp_orig = env.get(lp_key + '_ORIG')
if lp_orig is not None:
env[lp_key] = lp_orig # restore the original,None)
cmd = raw_input('Enter your command:')
out = Popen(cmd.split(),stderr=STDOUT,stdout=PIPE,env=env)
t,y = out.communicate()[0],out.returncode
print('output : ' + str(t))
print ('Return Code : ' + str(y))
附言不幸的是,cmd.split() 在某些情况下会失败,即当一个参数有空格时,比如 cmd='/usr/bin/ls "/home/user/my directory"' 会因 cmd.split() 而失败。在这种情况下, cmd = shlex.split(cmd,posix=True) 会工作得更好。但是 shlex.split() 在捕获标准输出时会失败,因此恕我直言,没有全能解决方案