使用临时环境变量运行 Python 脚本

新手上路,请多包涵

我有一个 Python 应用程序,它在 Kubernetes 配置中使用环境变量,例如:

 apiVersion: v1
kind: ConfigMap
metadata:
  name: my-config
  namespace: default
data:
  var1: foo
  var2: bar

---

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
  namespace: default
spec:
  containers:
    - envFrom:
      - configMapRef:
          name: my-config

因此,当应用程序被 Dockerized 并在 Kubernetes 农场上运行时,这很好。

然而,当在没有 Docker 和 Kubernetes 的 本地机器 上运行应用程序时,只有一个简陋的命令:

 python app.py

我必须让 Python 模块使用 os.getenv('var1') 即使没有 ConfigMap 或 Pod。

是否可以不需要在 Python 模块中添加额外的代码或向本地机器系统添加环境变量?

原文由 vahdet 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 606
2 个回答

您将需要一个“加载器”小程序,它会使用适当的变量调用第二个程序。当然,在 Python 中使用它也更方便,因为一切都已经设置好了——但它可能会一直存在

#!/usr/bin/env python3
import subprocess
import sys

import yaml

config = yaml.load(open(sys.argv[1]))["data"]
# Instead of "data" here, use the yaml path to the place in the configuration your variables are

cmdline = sys.argv[2:]
if cmdline[0].endswith(".py"):
    cmdline.insert(0, sys.executable)

result = subprocess.run(cmdline, env=config)
exit(result.returncode)

(当然你需要安装一些第 3 方库来读取 yaml 配置文件 - 我已经使用 PyYAML 来测试这个)

如果将上述脚本标记为可执行,则可以直接在命令行中使用它,而无需前缀“python3”——否则,如果将此文件命名为“runner.py”,则命令行可以是

python3 runner.py myconfig.yaml myscript.py parameter1 parameter2 parameter3

如果您需要传递当前环境并仅使用脚本中的变量进行更新,请在 .run 调用之前执行此操作:

 import os
...
config = yaml.load(...)[...]
config = {**os.environ, **config}

另外,看到这将使用与它运行的相同的 Python 解释器来执行脚本,以一种或多或少天真的方式(只检查文字“.py”文件扩展名)——如果你需要它更健壮,它建议对目标脚本执行 stat 并检查它是否可执行 - 然后直接调用它 - 并且只对其他文件使用当前的 Python 解释器。

或者修改你的代码

由于您有一个脚本作为入口点,并且想要简化它在第 3 次馅饼中的运行,您可以更改它而不是使用通用加载程序 - 在这种情况下,我建议添加一个额外的配置变量来指示变量是已经正确设置 - 所以当脚本在其容器中运行时,它什么都不做 - 否则,它会加载上述数据,并更新其 os.envrion。

换句话说,在代码的入口点,做一些事情:

 if not os.environ.get("EVERYTHING_SETUP"):
   import yaml
   config = yaml.load(open("myconfig.yaml"))["data"]
   os.environ.update(config)

原文由 jsbueno 发布,翻译遵循 CC BY-SA 4.0 许可协议

在 shell 中,您还可以在调用脚本之前简单地临时为环境变量分配值。根本不需要更改脚本。

考虑以下 app.py 只打印环境变量 ENV_PARAMENV_PARAM2

 #!/usr/bin/env python3
import os

print(os.environ['ENV_PARAM'])
print(os.environ['ENV_PARAM2'])

当变量没有设置并且你这样称呼它时

python app.py

你会得到一个 KeyError

KeyError: ‘ENV_PARAM’

当您改为在同一行中指定值并像这样调用它时

ENV_PARAM='foo' ENV_PARAM2='bar' python app.py

它工作正常。输出:

 foo
bar

这不会设置超出此范围的环境变量,因此如果您这样做

echo "$ENV_PARAM"

之后,它什么也不会返回。环境变量只是临时设置的,就像你需要的那样。

原文由 buddemat 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题