[英]Import bash variables from a python script
我已经看到很多从 bash 脚本内部运行 python 脚本的例子,或者将变量作为参数传递或使用导出来授予子 shell 访问权限,但我在这里尝试做相反的事情。
我正在运行一个 python 脚本并有一个单独的文件,我们称之为 myGlobalVariables.bash
myGlobalVariables.bash:
foo_1="var1"
foo_2="var2"
foo_3="var3"
我的 python 脚本需要使用这些变量。
举一个非常简单的例子:
我的PythonScript.py:
print "foo_1: {}".format(foo_1)
有没有办法直接导入它们? 另外,如果可能的话,我不想更改 bash 脚本,因为它是一个在其他地方多次引用的公共文件。
如果您的.bash
文件按照您的指示格式化 - 您可以通过imp
模块将其直接作为 Python 模块imp
。
import imp
bash_module = imp.load_source("bash_module, "/path/to/myGlobalVariables.bash")
print bash_module.foo_1
您还可以使用 os.environ:
重击:
#!/bin/bash
# works without export as well
export testtest=one
蟒蛇:
#!/usr/bin/python
import os
os.environ['testtest'] # 'one'
我对 python很陌生,所以我欢迎提供更多惯用方法的建议,但是下面的代码使用 bash 本身告诉我们通过首先在空环境( env -i bash
)中调用 bash 来告诉我们设置了哪些值我们将哪些变量设置为基线,然后我再次调用它并告诉 bash 获取您的“变量”文件,然后告诉我们现在设置了哪些变量。 删除一些误报和明显的空白行后,我遍历“附加”输出,寻找不在基线中的变量。 新看到的变量被拆分(小心地)并放入bash
字典中。 我已经离开(但注释掉了)我之前使用exec
在 python 中本地设置变量的想法,但我遇到了引用/转义问题,所以我切换到使用 dict 。
如果对“变量”文件的确切调用(路径等)与我的不同,那么您需要更改该值的所有实例——在list.remove()
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脚本:
#!/usr/bin/env 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")
# these get set when ". myGlobal..." runs and so are false positives
additional.remove("BASH_EXECUTION_STRING='. myGlobalVariables.bash; set'")
additional.remove('PIPESTATUS=([0]="0")')
additional.remove('_=myGlobalVariables.bash')
# I get an empty item at the end (blank line from subprocess?)
additional.remove('')
bash = {}
for assign in additional:
if not assign in baseline:
name, value = assign.split("=", 1)
bash[name]=value
#exec(name + '="' + value + '"')
print "New values:"
for key in bash:
print "Key: ", key, " = ", bash[key]
另一种方法:
受到Marat回答的启发,我想出了这个两阶段的 hack。 从 python 程序开始,我们称之为“阶段 1”,它使用subprocess
调用 bash 来获取变量文件,正如我上面的答案所做的那样,但它然后告诉 bash 导出所有变量,然后执行其余的您的 Python 程序,处于“第 2 阶段”。
第 1 阶段 python 程序:
#!/usr/bin/env python
import subprocess
status = subprocess.call(
['bash', '-c',
'. myGlobalVariables.bash; export $(compgen -v); exec ./stage2.py'
]);
第 2 阶段 python 程序:
#!/usr/bin/env python
# anything you want! for example,
import os
for key in os.environ:
print key, " = ", os.environ[key]
正如@theorifice 回答中所述,这里的技巧可能是这种格式化的文件可以被解释为 bash 和 python 代码。 但他的回答已经过时了。 不推荐使用imp
模块以支持importlib
。
由于您的文件具有“.py”以外的扩展名,您可以使用以下方法:
from importlib.util import spec_from_loader, module_from_spec
from importlib.machinery import SourceFileLoader
spec = spec_from_loader("foobar", SourceFileLoader("foobar", "myGlobalVariables.bash"))
foobar = module_from_spec(spec)
spec.loader.exec_module(foobar)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.