YAML,Docker Compose,空格和引号

41
在何种情况下,在使用docker-compose时,必须在YAML文件中使用引号?例如,
service:
  image: "my-registry/repo:tag1"
  environment:
    ENV1: abc
    ENV2: "abc"
    ENV3: "a b c"

如果需要使用空格,例如,在ENV3中必须使用引号包围环境变量吗?

2个回答

49

我在谷歌上搜索后,找到了一篇关于这个问题的博客文章,据我理解,它涉及到了这个问题。

我在这里引用最重要的部分:

plain scalars:
- a string
- a string with a \ backslash that doesn't need to be escaped
- can also use " quotes ' and $ a % lot /&?+ of other {} [] stuff

single quoted:
- '& starts with a special character, needs quotes'
- 'this \ backslash also does not need to be escaped'
- 'just like the " double quote'
- 'to express one single quote, use '' two of them'

double quoted:
- "here we can use predefined escape sequences like \t \n \b"
- "or generic escape sequences \x0b \u0041 \U00000041"
- "the double quote \" needs to be escaped"
- "just like the \\ backslash"
- "the single quote ' and other characters must not be escaped"

literal block scalar: |
  a multiline text
  line 2
  line 3

folded block scalar: >
  a long line split into
  several short
  lines for readability

我还没有看到过这种设置环境变量的docker-compose语法。文档建议使用简单的值,例如:

environment:
  - ENV1=abc
  - "ENV2=abc"

在这个特定的例子中,引号"'是可选的,根据我之前所说的。
要查看如何在环境变量中包含空格,您可以查看此so answer

2
谢谢这个。关于Docker Compose环境使用的风格,他们的文档在这里展示了两种不同的变体风格:https://docs.docker.com/compose/compose-file/#environment - David

6
是否需要使用引号取决于解析器。据我所知,Docker-compose仍然依赖于PyYAML模块,它实现了大部分YAML 1.1,并有一些自己的怪癖。
通常,只有在字符串可能被误解或与某些不是标量字符串的YAML构造相冲突时才需要用引号引起来。您还需要(双重)引号来表示不能用普通标量、单引号标量或块样式文字或折叠标量表示的内容。
误解
您需要引用看起来像其他数据结构的字符串:
- 布尔值:"True","False",但是PyYAML还假定替代词"是","否","打开","关闭"表示布尔值(所有小写字母和大写字母版本也应考虑)。请注意,YAML 1.2标准删除了对这些替代方案的引用。 - 整数:包括仅由数字组成的字符串。但还包括十六进制(0x123)和八进制数字(0123)。在YAML 1.2中,八进制数以0o123形式编写,但是PyYAML不支持此功能,因此最好引用两者。 - 特殊整数PyYAML仍然支持,但在YAML 1.2规范中也不支持,即:基于60的数字,由冒号(:)分隔,时间指示以及如果冒号之间/之后的值在00-59范围内,则也可以将MAC地址解释为这样的数字。 - 浮点数:如1E3(带有可选符号和尾数的字符串)应该用引号引起来。当然,如果3.14是一个字符串,那么它也需要加引号。并且带有尾数的60进制浮点数(在最终冒号后面的数字后面带有尾数)也应该加引号。 - 时间戳:2001-12-15T02:59:43.1Z,但也应该引用类似iso-8601的字符串,以防止它们被解释为时间戳。 - "null"值写为空字符串,或者~null(所有大小写类型都适用),因此与这些匹配的任何字符串都需要加引号。
上述引用可以使用单引号或双引号进行,也可以使用块样式文字或折叠标量。请注意,对于块样式,应使用|-resp。>-,以不引入原始字符串中没有的尾随换行符。
冲突
YAML为某些字符或字符组合分配了特殊含义。其中一些仅在字符串开头具有特殊含义,而另一些仅在字符串内部具有特殊含义。
  • 来自集合!&*?{[的字符通常表示特殊的YAML构造。其中一些可能取决于后面的字符而消除歧义,但我不会依赖这个。
  • 紧接着#的空格表示行末注释
  • 无论在哪里都可以使用键(在块模式下,在许多位置)冒号 + 空格组合(:)表示将要跟随一个值。如果该组合是您标量字符串的一部分,则必须引用它。

与误解一样,您可以使用单引号或双引号或块状文本或折叠标量。块状标量的第一行之外不能有行末注释。

PyYAML还会混淆纯量标量中的任何冒号+空格(即使这是在值中),因此请始终引用这些内容。

表示特殊字符

您可以在YAML文件中插入特殊字符或Unicode代码点,但是如果您想在所有情况下清晰地看到这些字符,您可能需要使用转义序列。在这种情况下,您必须使用双引号,这是唯一允许反斜杠转义的模式。例如:\u2029。此类转义的完整列表可以从标准中获取,但请注意,PyYAML没有实现例如\/(或者至少在我分叉该库时没有)。


找出何时需要引用或不引用的一个技巧是使用用于转储字符串的库。当潜在地转储纯量标量时,我的ruamel.yaml和由docker-compose使用的PyYAML都尝试读回字符串的纯量表示形式,如果结果与字符串不同,则需要应用引号。您也可以这样做:如果有疑问,请编写一个小程序,使用PyYAML的safe_dump()转储您拥有的字符串列表,并在PyYAML适用引号的任何位置应用引号。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接