YAML 语法
本页提供了正确 YAML 语法的基本概述,Ansible playbook(我们的配置管理语言)就是通过这种语法来表达的。
我们使用 YAML 是因为与 XML 或 JSON 等其他常见数据格式相比,它更易于人类阅读和编写。此外,大多数编程语言都提供了用于处理 YAML 的库。
您可能还希望同时阅读 使用 Playbook,以了解在实践中是如何使用它的。
YAML 基础
对于 Ansible 来说,几乎每个 YAML 文件都以列表(list)开始。列表中的每个项目都是一组键/值对(key/value pairs),通常被称为“哈希(hash)”或“字典(dictionary)”。因此,我们需要知道如何在 YAML 中编写列表和字典。
YAML 还有另一个小特点。所有 YAML 文件(无论是否与 Ansible 相关)都可以选择以 --- 开始,并以 ... 结束。这是 YAML 格式的一部分,用于指示文档的开始和结束。
列表的所有成员都是以 "- "(一个连字符和一个空格)开头且处于相同缩进级别的行。
---
# A list of tasty fruits
- Apple
- Orange
- Strawberry
- Mango
...
字典以简单的 key: value 形式表示(冒号后面必须紧跟一个空格)。
# An employee record
martin:
name: Martin D'vloper
job: Developer
skill: Elite
也可以实现更复杂的数据结构,例如字典列表、值为列表的字典,或者两者的混合。
# Employee records
- martin:
name: Martin D'vloper
job: Developer
skills:
- python
- perl
- pascal
- tabitha:
name: Tabitha Bitumen
job: Developer
skills:
- lisp
- fortran
- erlang
如果您愿意,字典和列表也可以用缩写形式表示。
---
martin: {name: Martin D'vloper, job: Developer, skill: Elite}
fruits: ['Apple', 'Orange', 'Strawberry', 'Mango']
这些被称为“流式集合(Flow collections)”。
Ansible 并不经常使用这些,但您还可以通过多种形式指定 布尔值(true/false)。
create_key: true
needs_agent: false
knows_oop: True
likes_emacs: TRUE
uses_cvs: false
如果您希望与默认的 yamllint 选项兼容,请在字典的布尔值中使用小写的 'true' 或 'false'。
可以使用 | 或 > 使值跨越多行。使用“字面量块标量(Literal Block Scalar)” | 跨行将保留换行符和任何尾随空格。使用“折叠块标量(Folded Block Scalar)” > 会将换行符转换为空格;它用于使原本非常长的行更易于阅读和编辑。在两种情况下,缩进都会被忽略。示例为:
include_newlines: |
exactly as you see
will appear these three
lines of poetry
fold_newlines: >
this is really a
single line of text
despite appearances
虽然在上面的 > 示例中所有换行符都被折叠为空间,但有两种方法可以强制保留换行符。
fold_some_newlines: >
a
b
c
d
e
f
或者,可以通过包含换行符 \n 字符来强制执行。
fold_same_newlines: "a b\nc d\n e\nf\n"
让我们在一个随机的 YAML 示例中结合目前学到的内容。这与 Ansible 实际上没有关系,但会让您对该格式有直观的感受。
---
# An employee record
name: Martin D'vloper
job: Developer
skill: Elite
employed: True
foods:
- Apple
- Orange
- Strawberry
- Mango
languages:
perl: Elite
python: Elite
pascal: Lame
education: |
4 GCSEs
3 A-Levels
BSc in the Internet of Things
这就是您开始编写 Ansible playbook 真正需要了解的所有关于 YAML 的知识。
注意事项
虽然您几乎可以在未加引号的标量中放入任何内容,但有一些例外。冒号后跟空格(或换行符) ": " 是映射的指示符。空格后跟井号 " #" 表示注释的开始。
因此,以下内容将导致 YAML 语法错误:
foo: somebody said I should put a colon here: so I did
windows_drive: c:
……但这样就可以正常工作:
windows_path: c:\windows
对于后面跟着空格或处于行尾的冒号,您需要使用引号包裹哈希值。
foo: 'somebody said I should put a colon here: so I did'
windows_drive: 'c:'
……这样冒号就会被保留。
或者,您可以使用双引号。
foo: "somebody said I should put a colon here: so I did"
windows_drive: "c:"
单引号和双引号的区别在于,在双引号中您可以使用转义字符。
foo: "a \t TAB and a \n NEWLINE"
允许的转义列表可以在 YAML 规范的 “Escape Sequences”(YAML 1.1)或 “Escape Characters”(YAML 1.2)中找到。
以下是无效的 YAML:
foo: "an escaped \' single quote"
此外,Ansible 使用 “{{ var }}” 表示变量。如果冒号后的值以 “{” 开始,YAML 会认为它是一个字典,因此您必须像这样对其加引号:
foo: "{{ variable }}"
如果您的值以引号开始,则整个值必须被引号包裹,而不仅仅是其中一部分。这里有一些关于如何正确使用引号的额外示例:
foo: "{{ variable }}/additional/string/literal"
foo2: "{{ variable }}\\backslashes\\are\\also\\special\\characters"
foo3: "even if it is just a string literal it must all be quoted"
非法变量名
foo: "E:\\path\\"rest\\of\\path
除了 ' 和 " 之外,还有许多特殊(或保留)字符不能用作未加引号标量的第一个字符:[] {} > | * & ! % # ` @ ,。
您还应该注意 ? : -。在 YAML 中,如果后面跟着非空格字符,它们允许出现在字符串的开头,但不同的 YAML 处理器实现有所不同,因此最好使用引号。
在流式集合(Flow Collections)中,规则更加严格。
a scalar in block mapping: this } is [ all , valid
flow mapping: { key: "you { should [ use , quotes here" }
布尔值转换很有用,但当您需要字面量 yes 或其他布尔值作为字符串时,这可能会成为一个问题。在这种情况下,请直接使用引号。
non_boolean: "yes"
other_string: "False"
YAML 会将某些字符串转换为浮点值,例如字符串 1.0。如果您需要指定版本号(例如在 requirements.yml 文件中),如果该值看起来像浮点值,则需要对其加引号。
version: "1.0"
另请参阅
- 使用 Playbook
了解 playbook 能做什么以及如何编写/运行它们。
- YAMLLint
如果您遇到问题,YAML Lint(在线版)可以帮助您调试 YAML 语法。
- Wikipedia YAML 语法参考
一份优秀的 YAML 语法指南
- YAML 1.1 规范
YAML 1.1 的规范,目前 PyYAML 和 libyaml 正在实现该规范。
- YAML 1.2 规范
为了完整起见,YAML 1.2 是 1.1 的继任者。
- 交流方式
有疑问?需要帮助?想分享你的想法?请访问 Ansible 通信指南