テキストファイルがあります/etc/default/foo
これには1行が含まれます。
FOO="/path/to/foo"
pythonスクリプトでは、変数FOOを参照する必要があります。
ファイルを「ソース」にする最も簡単な方法は何ですか/etc/default/foo
into pythonスクリプト、bashで行うのと同じ?
. /etc/default/foo
execfile を使用できます。
execfile("/etc/default/foo")
ただし、これによりファイルの内容がプログラムソースにそのまま評価されることに注意してください。ソースを完全に信頼できない限り、潜在的なセキュリティ上の危険があります。
また、ファイルは有効なpython構文(指定されたサンプルファイル))である必要があります。
次のように_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
ループなどを使用して、さらに数行で同じことを実現できます。
そしてもちろん、ファイルに_${somevar:-value_if_not_set}
_のようなシェルスタイルの変数展開が含まれている場合、これは機能しません(独自のシェルスタイル変数パーサーを記述しない限り)。
ファイル拡張子が.pyであるこのコンテンツを含む「テキスト」ファイルがある場合は、いつでも実行できることに注意してください。
import mytextfile
print(mytestfile.FOO)
もちろん、これは、テキストファイルがPythonに関する限り、構文的に正しいことを前提としています。私が取り組んでいるプロジェクトで、これに似た何かをしました。いくつかのテキストファイルをPythonファイル。奇抜ですが、検討する価値があるかもしれません。
別のアプローチを与えるために、元のファイルが
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"]
@jilと同じ答えですが、その答えはPythonの歴史的なバージョンに固有のものです。
現代ではPython(3.0+):
_exec()
_
execfile()
を置き換えます
この種のことを行うには、いくつかの方法があります。
含まれるデータがPythonの構文に対応している限り、ファイルをモジュールとしてimport
できます。ただし、問題のファイルは、スクリプトと同じディレクトリにある.py
であるか、imp
(またはバージョンに応じてimportlib
)を使用する必要があります ここのように 。
別の解決策(私の好みがあります)は、任意の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
を使用する方が簡単な場合があります。
それが役立つことを願っています!
私のアプローチは次のとおりです。自分で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)
この行は、シェルスクリプト内の行を反復処理し、等号を持つ行のみを処理します(変数の割り当てを検出する確実な方法ではなく、最も単純な方法)。次に、これらの行を関数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)