首页 > 解决方案 > 在 ubuntu 上编译并在 SuSe 12 SP4 上运行的 Pyinstaller 子进程的奇怪行为

问题描述

我注意到在 Ubuntu 16 上使用 pyinstaller 编译的子进程的一些奇怪行为在 ubuntu 16 上运行良好,但在 SuSe12 SP4 上失败。想知道是否有人可以阐明并告诉我我错过了哪些微不足道的信息?

基本上,我有一个简单的脚本:

import os, sys, subprocess
def get_all_outputs(cmd):
    proc = subprocess.Popen(cmd,
                            stdout=subprocess.PIPE,
                            stderr=subprocess.PIPE,
                            shell=True,
                            universal_newlines=True)
    std_out, std_err = proc.communicate()
    return proc.returncode, std_out, std_err
cmd = raw_input('CMD:')
print get_all_outputs(cmd)

这可以作为 Ubuntu 16 上的普通 python 文件或 pyinstaller 文件正常工作......

root@ubuntu16:~/cert/dist# ./retcode
CMD:openssl x509 -in /root/cert_new/mycert.cer


(0, '-----BEGIN CERTIFICATE-----\nMIIFmTCCBIGgAwIBAgITQwAAAGqQd2QfUVAHwQABAAAAajANBgkqhkiG9w0BAQsF\nADBGMRUwEwYKCZImiZPyLGQBGRYFbG9jYWwxFjAUBgoJkiaJk/IsZAEZFgZhdmFt\nYXIxFTATBgNVBAMTDGF2YW1hci1EQy1DQTAeFw0yMDEyMjkxMjAyNDhaFw0yMjEy\nMjkxMjAyNDhaMHYxCzAJBgNVBAYTAkFVMQwwCgYDVQQIEwNOU1cxDzANBgNVBAcT\nBlN5ZG5leTERMA8GA1UEChMIRGVsbCBFTUMxEDAOBgNVBAsTB1N1cHBvcnQxIzAh\nBgNVBAMTGm5lbzEtc3lWwMBMA0GCSqGSIb3DQEBCwUAA4IBAQBjH2ubfVxCC42LVURTZUog/vJZ\nctAEBDUW3VaeRCMWD3dvB0loc0llGaXQVafh0Q2cW8Uy0qMexPcUUwp8OjbtwcBo\n3TkEApBABgX/JC9P+BXCK3NiYze1SAjsgcdeZaS0t3HLlgwc8vZSotXco+mwZM9S\nTtrU1RqU4kkqhR5+wjPT8ffLFyZNBCdDKUOF3wxsr/0uUpfm9Bnt3DahoN4dwHvI\nOvi1DSV6ob84VXKT3ehMqt27ZW5dtLQdpzINADHDHlitTAUAO+CdO3LltqobQbf8\niK8fmnmSWHVF8vA3mmIfANLILZ6XKASgo2D2RU0jPjbkWi3nPY+2aRPGS1wJ\n-----END CERTIFICATE-----\n', '')

但是,当我将编译后的文件 scp 到 SuSe12SP4 时,我从未得到输出,而是不断抛出错误代码 127 以及如下所示的有趣消息:

neo_suse12sp4:~/pp # ./retcode
CMD:/usr/local/ssl/bin/openssl x509 -in /root/pp/mycert.cer

(127, '', '/bin/sh: /tmp/_MEIOqKDWs/libreadline.so.6: no version information available (required by /bin/sh)\n/usr/local/ssl/bin/openssl: relocation error: /usr/local/ssl/bin/openssl: symbol i2d_DHxparams, version OPENSSL_1.0.0 not defined in file libcrypto.so.1.0.0 with link time reference\n')

我什至尝试使用 openssl 和证书的完整路径,但它根本不起作用。

neo_suse12sp4:~/pp # which openssl
/usr/local/ssl/bin/openssl

如果有人可以在这里为我提供帮助,我将不胜感激。我会非常感谢你。谷歌和现有的关于 SO 的文章似乎无法解决这个问题。

标签: pythonubuntusubprocesspyinstallersuse

解决方案


好吧,看来我自己找到了出路。这看起来像是在 SuSe 12 SP4 系统上找到的 openssl 可执行文件与从 Ubuntu 16 构建系统收集的 libcrypto.so 库不兼容(现在正在冻结应用程序及其子进程中覆盖系统一)。

我们需要修改子进程的 LD_LIBRARY_PATH 以使系统的库优先于捆绑的库。

非常感谢 github 上的 @Rok Mandeljc (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 命令

def run_command(cmd): #returns the output of a program
    proc = subprocess.Popen(cmd,stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, shell=True, universal_newlines=True, env=env)
    std_out, std_err = proc.communicate()
    return std_out

更多信息:https ://pyinstaller.readthedocs.io/en/stable/runtime-information.html?ld-library-path-libpath-considerations#ld-library-path-libpath-considerations


推荐阅读