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

nukf8bse  于 2022-11-16  发布在  Shell
关注(0)|答案(3)|浏览(260)

我有一个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模块中添加额外的代码或者在本地机器系统中添加环境变量?

0dxa2lsx

0dxa2lsx1#

在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
关键字错误:'ENV_PARAM'
当您改为在同一行中指定值并像这样调用它时

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

它工作正常。输出:

foo
bar

这将不会设置超出该值的环境变量,因此如果

echo "$ENV_PARAM"

之后,它将不返回任何内容。2环境变量只是临时设置的,就像你所要求的那样。

pcww981p

pcww981p2#

您可以通过在os模块的environ字典中添加键-值对来设置所需的环境变量。

import os 

os.environ['intended var'] = 'intended value'

样品运行

>>> os.getenv('intended var')
'intended value'
cbeh67ev

cbeh67ev3#

你需要有一个“loader”小程序,它将用适当的变量调用第二个程序沿着

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

(Of当然,你需要安装一些第三方的lib来读取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解释器。

或修改您的代码

由于您有一个脚本作为入口点,并且希望简化3rdy paties的运行,您可以更改它,而不是使用通用的加载器-在这种情况下,我会重新添加一个额外的配置变量,以指示变量已经正确设置-因此,当脚本在其容器中运行时,它什么也不做-否则,它会如上所述加载数据,并更新其os. envrion。
换句话说,在代码的入口点,执行沿着操作:

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

相关问题