6

我有一个 shell 脚本,其中设置了某些参数,例如:
k.sh:

export var="value"
export val2="value2"

然后我有一个 python 脚本,我在其中调用 shell 脚本并想使用这些环境变量
ex1.py:

import subprocess
import os
subprocess.call("source k.sh",shell=True)
print os.environ["var"]

但是我得到了一个KeyError
如何在我的 Python 脚本中使用这些 shell 变量?

4

6 回答 6

2

您可以获取k.sh 运行 Python one-liner 以将其内容打印os.environ为 JSON。然后用于json.loads将该输出转换回主进程中的字典:

import subprocess
import os
import json
PIPE = subprocess.PIPE
output = subprocess.check_output(
    ". ~/tmp/k.sh && python -c 'import os, json; print(json.dumps(dict(os.environ)))'",
    shell=True)
env = json.loads(output)
print(env["var"])

产量

value
于 2013-05-14T18:40:06.580 回答
2

subprocess.call在一个新进程中启动一个 shell,该进程调用source. 无法从子进程修改进程中的环境。

于 2013-05-14T18:21:17.473 回答
2

如果要设置环境然后运行 ​​Python 脚本,那么请设置环境并使用runner运行 Python 脚本:

跑步者

#! /bin/bash
. k.sh
exec ex1.py

就是这样。

ex1.py

#import subprocess
import os
#subprocess.call("source k.sh",shell=True)
print os.environ["var"]
于 2013-05-15T05:14:52.903 回答
0

/u/unutbu 已经回答了这个问题。但是我在他的代码中修复了几个错误:

def run_external_script(script):
    if is_windows():
        command = script+" && python -c \"import os; print dict(os.environ)\""
    else:
        command = ". "+ script+" && python -c 'import os; print dict(os.environ)'"

    output = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True).communicate()[0]
    r = re.compile('{.*}')
    m = r.search(output)
    try:
        env = eval(m.group(0))
    except:
        error( "Something went wrong in " + script )
        error( output )
    return env

有几个小区别:

  • 此代码适用于 windows/linux
  • 我用 subprocess.call 替换了 subprocess.check_output,check_output 需要 Python 2.7
  • 当我运行他的代码时,脚本中的 std 也会打印在输出变量中。所以我用一个re来抓取字典中两个{}之间的所有东西,比如{'var1'=1,'var2'='x'}。
  • 我没有使用 json,而是使用了 python 的 eval。有注射的机会,所以使用它需要您自担风险。如{; exit(1); }
于 2014-07-16T19:42:14.063 回答
0

正如切普纳所指出的那样。您的子流程部分是单独运行的。必须在启动 python 脚本之前使用环境变量。

例如:

C:\Users\anton\Desktop\githubs>echo %x%
y

C:\Users\anton\Desktop\githubs>python
Python 2.7.3 (default, Apr 10 2012, 23:31:26) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> os.environ['x']
'y'
>>>

但是,在启动脚本之前获取环境变量将向下遍历,或者如果您对子进程调用执行多个命令,那么在获取它之后也会很好。例如:

import subprocess
import os
x = subprocess.call("source k.sh",shell=True, STDIN=subprocess.PIPE, STDOUT=subprocess.PIPE)
y = subprocess.call("echo $var",shell=True, STDIN=x.stdout, STDOUT=subprocess.PIPE)

如前所述,从未尝试过。在发布之前获取它。

于 2013-05-14T18:22:52.600 回答
0

如果您在 Windows 上,您可以使用 powershell 设置环境变量

os.system("powershell.exe [System.Environment]::SetEnvironmentVariable('key', 'value','User')")

值得注意的是,在您的应用程序可以使用变量之前,您需要重新启动应用程序以允许它读取更新的变量...

然后你可以访问

yourValue = os.environ['key']
于 2019-10-10T03:12:34.110 回答