スクリプトで解析する必要があるyamlファイルで環境変数「PATH」を使用する必要があります。
これは、端末で設定した環境変数です。
$ echo $PATH
/Users/abc/Downloads/tbwork
これは私のsample.ymlです:
---
Top: ${PATH}/my.txt
Vars:
- a
- b
このyamlファイルをスクリプトで解析すると、PATH
変数の実際の値が表示されません。
これは私のスクリプトです:
import yaml
import os
import sys
stream = open("sample.yml", "r")
docs = yaml.load_all(stream)
for doc in docs:
for k,v in doc.items():
print k, "->", v
print "\n",
出力:
Top -> ${PATH}/my.txt
Vars -> ['a', 'b']
予想される出力は次のとおりです。
Top -> /Users/abc/Downloads/tbwork/my.txt
Vars -> ['a', 'b']
間違った方法でやっている場合、誰かが正しい方法を見つけるのを手伝ってくれますか?
PY-yamlライブラリは、デフォルトでは環境変数を解決しません。環境変数を定義する正規表現を見つけ、それを解決する関数を実行する暗黙的なリゾルバーを定義する必要があります。
yaml.add_implicit_resolver
およびyaml.add_constructor
を使用して実行できます。以下のコードでは、YAML値の$ {env変数}に一致するリゾルバーを定義し、関数path_constructorを呼び出して環境変数を検索しています。
import yaml
import re
import os
path_matcher = re.compile(r'\$\{([^}^{]+)\}')
def path_constructor(loader, node):
''' Extract the matched value, expand env variable, and replace the match '''
value = node.value
match = path_matcher.match(value)
env_var = match.group()[2:-1]
return os.environ.get(env_var) + value[match.end():]
yaml.add_implicit_resolver('!path', path_matcher)
yaml.add_constructor('!path', path_constructor)
data = """
env: ${VAR}/file.txt
other: file.txt
"""
if __name__ == '__main__':
p = yaml.safe_load(data)
print(os.environ.get('VAR')) ## /home/abc
print(p['env']) ## /home/abc/file.txt
グローバル/デフォルトのyaml Loaderを変更したくない場合に、新しいLoaderクラスを使用する代替バージョンを次に示します。
さらに重要なことは、環境変数だけではなく、例えばpath/to/${SOME_VAR}/and/${NEXT_VAR}/foo/bar
path_matcher = re.compile(r'.*\$\{([^}^{]+)\}.*')
def path_constructor(loader, node):
return os.path.expandvars(node.value)
class EnvVarLoader(yaml.SafeLoader):
pass
EnvVarLoader.add_implicit_resolver('!path', path_matcher, None)
EnvVarLoader.add_constructor('!path', path_constructor)
with open(configPath) as f:
c = yaml.load(f, Loader=EnvVarLoader)