在 SuSe 12 SP4 上 ubuntu 和 运行 上编译的 Pyinstaller 的子进程的奇怪行为

Weird behavior of subprocess with Pyinstaller compiled on ubuntu and run on SuSe 12 SP4

我注意到在 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)

python 文件或 Ubuntu 上的 pyinstaller 文件正常工作 16...

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

如果有人能在这里帮助我,我将不胜感激。我会非常感谢你的。 Google SO 上的现有文章似乎与此问题不符。

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

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

万分感谢@Rok Mandeljc (rokm) 在 github 上帮助我解决这个问题。将它张贴在这里以防其他人撞到他们的头会很容易解决这个问题。

解决方案:

###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)

接下来,将环境变量添加到 subprocess 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