Python subprocess.Popen 传递修改后的环境以在 postinst 脚本中使用新的环境变量

Python subprocess.Popen pass modified environment to use new environment varibels in postinst script

我有一台服务器可以安装包含 postinst 脚本的不同 debian 软件包。

一些软件包需要修改后的环境,其中包含一些要连接的端口。

当我调用服务器安装包时,我在请求中传递了一个包含自定义端口的对象参数 vars{'vars': {'CUSTOM_PORT_1': '7755', 'CUSTOM_PORT_2': '7766'}}

在我的代码中,我将 subprocess.Popen 调用到 运行 将安装 debian 软件包的命令。这是我的代码:

def open_process(command, app_vars=None):
    my_env = os.environ.copy()
    if app_vars:
        my_env.update(app_vars)

    p = subprocess.Popen(['sudo', 'dpkg', '-i', 'path-to-package'], env=my_env, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False)
    
    output, err = p.communicate()
    return_code = p.returncode
    return output, err, return_code

我预计修改后的环境将通过 env=my_env 传递给 postinst 脚本,这样我就可以将它们打印出来。 postinst 脚本 运行 是一个使用来自修改后的环境的这些端口的应用程序,因此我必须在 运行 应用程序之前导出它们。这是 postinst 脚本中的代码:

#!/bin/bash
.
.
.
echo "CUSTOM_PORT_1:$CUSTOM_PORT_1"
echo "CUSTOM_PORT_2:$CUSTOM_PORT_2"

export APP_PORT_1=$CUSTOM_PORT_1
export APP_PORT_2=$CUSTOM_PORT_2 

echo "APP_PORT_1:$APP_PORT_1"
echo "APP_PORT_2:$APP_PORT_2"
.
.
.
*run-the-app*

不幸的是,这是输出:

CUSTOM_PORT_1: 
CUSTOM_PORT_2:

APP_PORT_1: 
APP_PORT_2:

我必须提到我还尝试了 subprocess.Popen 行的其他几种方式:

1.

p = subprocess.Popen(['sudo dpkg -i /path-to-package', env=my_env, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
def open_process(command, app_vars=None):
    if app_vars:
        for key in app_vars:
           os.environ[key] = app_vars.get(key)

    p = subprocess.Popen(['sudo', 'dpkg', '-i', 'path-to-package'], env={**os.environ}, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False)

有什么我遗漏的吗?

我的期望合理吗?

这可能吗?

好吧,我刚刚了解到,当 运行 带有 sudo 的命令时,本地用户环境变量与 root 用户不同。

为了在 运行 带有 sudo 的命令时保留环境变量,您应该按照此答案 how-to-keep-environment-variables-when-using-sudo 中的描述添加标志 -E

我从 how-to-keep-environment-variables-when-using-sudo 手册页中复制了引述:

-E, --preserve-env
Indicates to the security policy that the user wishes to preserve their existing environment variables. The security policy may return an error if the user does not have permission to preserve the environment.

一旦我将命令字符串更改为 sudo -E dpkg -i path-to-packagepostinst 脚本就能够按我的预期打印出变量:

CUSTOM_PORT_1: 7755
CUSTOM_PORT_2: 7766

APP_PORT_1: 7755
APP_PORT_2: 7766