我对Python非常陌生,因此欢迎提出更惯用的方法。以下代码使用bash本身告诉我们哪些值被设置,首先通过调用一个空环境的bash(env -i bash
)来确定基线中设置了哪些变量,然后再次调用它并告诉bash来源化您的“variables”文件,最后告诉我们现在设置了哪些变量。
删除一些误报和明显为空的行之后,我遍历“additional”输出,查找不在基线中的变量。新看到的变量被拆分(小心翼翼)并放入bash
字典中。
我保留了以前使用exec
在Python中本地设置变量的想法(但注释掉了),但我遇到了引号/转义问题,所以我改变了思路,使用了字典。
如果您的“variables”文件的确切调用(路径等)与我的不同,则需要更改该值的所有实例-在subprocess.check_output()
调用中,在list.remove()
调用中。
这是我使用的示例变量文件,只是为了演示可能发生的一些事情:
foo_1="var1"
foo_2="var2"
foo_3="var3"
if [[ -z $foo_3 ]]; then
foo_4="test"
else
foo_4="testing"
fi
foo_5="O'Neil"
foo_6='I love" quotes'
foo_7="embedded
newline"
...这是Python脚本:
import subprocess
output = subprocess.check_output(['env', '-i', 'bash', '-c', 'set'])
baseline = output.split("\n")
output = subprocess.check_output(['env', '-i', 'bash', '-c', '. myGlobalVariables.bash; set'])
additional = output.split("\n")
additional.remove("BASH_EXECUTION_STRING='. myGlobalVariables.bash; set'")
additional.remove('PIPESTATUS=([0]="0")')
additional.remove('_=myGlobalVariables.bash')
additional.remove('')
bash = {}
for assign in additional:
if not assign in baseline:
name, value = assign.split("=", 1)
bash[name]=value
print "New values:"
for key in bash:
print "Key: ", key, " = ", bash[key]
另一种方法:
在Marat的答案的启发下,我想出了这个两阶段的黑客。先用一个Python程序开始,让我们称之为“第一阶段”,它使用subprocess
调用bash来源文件变量,就像我上面的答案一样,但是然后告诉bash导出所有变量,然后执行你Python程序的其余部分,也就是“第二阶段”。
第一阶段Python程序:
#!/usr/bin/env python
import subprocess
status = subprocess.call(
['bash', '-c',
'. myGlobalVariables.bash; export $(compgen -v); exec ./stage2.py'
]);
第二阶段的Python程序:
import os
for key in os.environ:
print key, " = ", os.environ[key]
var_name=var_val
- 这样就没有 shell 扩展、命令替换等。 - theorifice