正确的做法是使用脚本语言和 YAML 解析库来提取您感兴趣的字段。
这是一个如何在 Python 中执行此操作的示例。如果您真的这样做,您可能会将其拆分为多个功能并获得更好的错误报告。这只是为了说明calico.yaml 的格式带来的一些困难,calico.yaml 是多个 YAML 文档串联在一起,而不仅仅是一个。您还必须遍历文档内部的一些列表才能提取您感兴趣的字段。
#!/usr/bin/env python3
import yaml
def foo():
with open('/tmp/calico.yaml', 'r') as fil:
docs = yaml.safe_load_all(fil)
doc = None
for candidate in docs:
if candidate["kind"] == "DaemonSet":
doc = candidate
break
else:
raise ValueError("no YAML document of kind DaemonSet")
l1 = doc["spec"]
l2 = l1["template"]
l3 = l2["spec"]
l4 = l3["containers"]
for containers_item in l4:
l5 = containers_item["env"]
env = l5
for entry in env:
if entry["name"] == "CALICO_IPV4POOL_CIDR":
return entry["value"]
raise ValueError("no CALICO_IPV4POOL_CIDR entry")
print(foo())
但是,有时您现在就需要一个解决方案,而 shell 脚本非常擅长。
如果您要访问 API 端点,那么 YAML 通常会打印得很漂亮,这样您就可以通过在任意 YAML 上无法使用的方式提取文本。
类似下面的东西应该是相当健壮的:
cat </tmp/calico.yaml | grep -A1 CALICO_IPV4POOL_CIDR | grep value: | cut -d: -f2 | tr -d ' "'
虽然值得在末尾使用正则表达式检查提取的值确实是有效的 IPv4 CIDR 表示法。
这里的关键是grep -A1 CALICO_IPV4POOL_CIDR。
您提到的双元素字典(如下所示)将始终显示为一个块,因为它是 YAML 文档的子树。
- name: CALICO_IPV4POOL_CIDR
value: "192.168.0.0/16"
calico.yaml 中的键通常不按字母顺序排序,但在{"name": <something>, "value": <something else>} 结构中,name 始终出现在value 之前。