我有一个文本文件/etc/default/foo
,其中包含一行:
FOO="/path/to/foo"
在我的python脚本中,我需要引用变量FOO。
" source"最简单的方法是什么?文件/etc/default/foo
进入我的python脚本,就像我在bash中做的那样?
. /etc/default/foo
答案 0 :(得分:10)
您可以使用execfile:
execfile("/etc/default/foo")
但请注意,这会将文件内容评估为您的程序源。除非您完全信任来源,否则存在潜在的安全隐患。
这也意味着该文件需要是有效的python语法(您的给定示例文件是)。
答案 1 :(得分:3)
如果您知道某些它只包含VAR="QUOTED STRING"
个样式变量,请执行以下操作:
FOO="some value"
然后你可以这样做:
>>> with open('foo.sysconfig') as fd:
... exec(fd.read())
哪个可以帮到你:
>>> FOO
'some value'
(这实际上与execfile()
解决方案相同
在另一个答案中建议。)
这种方法具有重大的安全隐患;如果您的文件包含FOO="some value"
,而不是os.system("rm -rf /")
:
>>> with open('foo.sysconfig') as fd:
... settings = {var: shlex.split(value) for var, value in [line.split('=', 1) for line in fd]}
那你就麻烦了。
或者,你可以这样做:
settings
它会为您提供一个字典>>> settings
{'FOO': ['some value']}
,其中包含:
settings = {...}
for
行正在使用http://www.postgresql.org/message-id/CFF47E56EA077241B1FFF390344B5FC10ACB1C0C@webmail.begavalley.nsw.gov.au。你可以用更多的${somevar:-value_if_not_set}
循环来完成同样的事情。等等。
当然,如果文件包含像rcells = r.cells
这样的shell样式变量扩展,那么这不会起作用(除非你编写自己的shell样式变量解析器)。
答案 2 :(得分:3)
请注意,如果您的“文本”文件中包含.py作为文件扩展名的内容,您可以随时执行以下操作:
{{1}}
当然,这假设文本文件在语法上是正确的,就Python而言。在我参与的项目中,我们做了类似的事情。将一些文本文件转换为Python文件。古怪,但也许值得考虑。
答案 3 :(得分:3)
只是提供不同的方法,请注意,如果您的原始文件设置为
export FOO=/path/to/foo
您可以执行source /etc/default/foo; python myprogram.py
(或. /etc/default/foo; python myprogram.py
),并且在myprogram.py
内,在源文件中导出的所有值都在os.environ中可见,例如
import os
os.environ["FOO"]
答案 4 :(得分:2)
答案与@jil相同,但该答案特定于某些历史版本的Python。
在现代Python(3.0或更高版本)中:
exec()
替换execfile()
答案 5 :(得分:1)
有几种方法可以做到这一点。
您确实可以import
将该文件作为模块,只要它包含的数据与python的语法相对应即可。但是,相关文件与您的脚本位于同一目录中.py
,您要么使用imp
(或importlib
,具体取决于您的版本){{3 }}
另一个解决方案(我有偏好)可以使用任何python库都可以解析的数据格式(作为一个例子,我想到了JSON)。
/ etc / default / foo:
{"FOO":"path/to/foo"}
在你的python代码中:
import json
with open('/etc/default/foo') as file:
data = json.load(file)
FOO = data["FOO"]
## ...
file.close()
这样,你就不会冒险执行一些不确定的代码......
您可以选择,具体取决于您的喜好。如果您的数据文件是由某些脚本自动生成的,那么保留FOO="path/to/foo"
之类的简单语法并使用imp
可能会更容易。
希望它有所帮助!
答案 6 :(得分:0)
这是我的方法:自己解析bash文件并仅处理变量赋值行,例如:
FOO="/path/to/foo"
以下是代码:
import shlex
def parse_shell_var(line):
"""
Parse such lines as:
FOO="My variable foo"
:return: a tuple of var name and var value, such as
('FOO', 'My variable foo')
"""
return shlex.split(line, posix=True)[0].split('=', 1)
if __name__ == '__main__':
with open('shell_vars.sh') as f:
shell_vars = dict(parse_shell_var(line) for line in f if '=' in line)
print(shell_vars)
看一下这个片段:
shell_vars = dict(parse_shell_var(line) for line in f if '=' in line)
这一行遍历shell脚本中的行,只处理那些具有等号的行(不是一种检测变量赋值的万无一失的方法,但最简单)。接下来,将这些行运行到函数parse_shell_var
中,该函数使用shlex.split
来正确处理引号(或缺少引号)。最后,这些碎片被组装成字典。该脚本的输出是:
{'MOO': '/dont/have/a/cow', 'FOO': 'my variable foo', 'BAR': 'My variable bar'}
以下是 shell_vars.sh 的内容:
FOO='my variable foo'
BAR="My variable bar"
MOO=/dont/have/a/cow
echo $FOO
这种方法有几个优点:
这种方法并不完美,它有一些局限性:
它无法正确解析基于其他变量或命令构建的值。这意味着,对于以下行,它将失败:
FOO=$BAR
FOO=$(pwd)