在Python脚本中使用shell变量不起作用

时间:2013-05-14 18:16:40

标签: python linux shell

我有一个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变量?

6 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:1)

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

答案 2 :(得分:1)

如果要设置环境然后运行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"]

答案 3 :(得分: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)

如上所述,从来没有尝试过那个。在发布之前来源。

答案 4 :(得分: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来抓取两个{}之间的字典,例如{&#39; var1&#39; = 1,&#39; var2&#39; =&#39; x&#39;}。
  • 而不是使用json,我使用了python的eval。有注射的机会,所以使用它需要您自担风险。例如{; exit(1); }

答案 5 :(得分:0)

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

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

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

然后您可以使用

yourValue = os.environ['key']