YAML,Docker Compose,空格和引号

时间:2018-10-31 12:04:08

标签: docker-compose yaml

在什么情况下必须在YAML文件中使用引号,尤其是在使用docker-compose时。

例如,

service:
  image: "my-registry/repo:tag1"
  environment:
    ENV1: abc
    ENV2: "abc"
    ENV3: "a b c"

例如,如果需要空格,是否必须在环境变量周围使用引号,如ENV3中所述?

2 个答案:

答案 0 :(得分:4)

经过一番谷歌搜索,我发现了一篇博客文章blog post 据我所知,触及了这个问题。

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

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语法来设置环境变量。 Documentation建议使用简单的值,例如

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

根据我之前所说,在此特定示例中,引号"'是可选的。

要查看环境变量中如何包含空格,您可以查看此so answer

答案 1 :(得分:2)

是否需要引号取决于解析器。由Docker组成的AFAIK仍依赖于PyYAML模块,该模块实现了YAML 1.1的大部分功能,并具有一些自己的怪癖。

通常,您只需要引用可能会被误解或与某些非标量字符串的YAML构造冲突的内容。对于无法用普通标量,单引号标量或块样式文字或折叠标量表示的事物,您还需要使用双引号。

曲解

您需要引用类似于其他数据结构的字符串:

  • 布尔值:“ True”,“ False”,但PyYAML还假定其他选项如“ Yes”,“ No”,“ On”,“ Off”等表示布尔值(并且所有小写字母,所有大写字母都应考虑在内)以及)。请注意,YAML 1.2标准删除了对这些替代方法的引用。
  • 整数:这包括仅由数字组成的字符串。还有十六进制(0x123)和八进制数(0123)。 YAML 1.2中的八进制表示为0o123,但是PyYAML不支持此功能,但是最好同时引用两者。 PyYAML仍然支持但在YAML 1.2规范中仍然不支持的特殊整数是六进制数:以冒号(:分隔的基数60,时间指示以及MAC地址也可以这样解释,如果之间/之后的值冒号的范围是00-59
  • 浮点数:应引用1E3之类的字符串(带有可选的符号ans尾数)。当然,如果它是字符串,也需要用3.14引起来。并且还应引用六十进制浮点数(在最后一个冒号之后的数字为尾数)。
  • 时间戳:2001-12-15T02:59:43.1Z,还应引用iso-8601之类的字符串,以防止将它们解释为时间戳
  • null值被写为空字符串,分别为~Null(在所有大小写类型中),因此任何与这些字符串匹配的字符串都必须用引号引起来。

以上引用可以使用单引号或双引号进行,也可以使用块样式文字或折叠标量。请注意,对于块样式,您应使用|-和。 >-,以便不引入原始字符串中没有的结尾换行符。

冲突

YAML为某些字符或字符组合赋予特殊含义。其中一些仅在字符串开头才具有特殊含义,而其他一些则仅在字符串内。

    集合!&*?{[中的
  • 个字符通常表示特殊的YAML构造。其中某些可能会因以下字符而有所歧义,但我不会依赖于此。
  • 空格后跟#表示行注释的结尾
  • 在可能有键的任何地方(并且在很多地方都处于块模式下),冒号+空格(:)的组合表示将跟随一个值。如果该组合是标量字符串的一部分,则必须引用。

与误解一样,您可以使用单引号或双引号或块样式的文字或折叠标量。除了块样式标量的第一行之外,没有行尾注释。

PyYAML还会被普通标量内的任何冒号+空格所混淆(即使该值位于值中),因此请始终引用它们。

代表特殊字符

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


找出要引用什么内容的一个技巧是使用用于转储您拥有的字符串的库。我的ruamel.yaml和docker-compose使用的PyYAML,当潜在地转储普通标量时,都尝试回读(是的,通过解析结果)字符串的普通标量表示形式,如果结果不同于字符串,很明显需要使用引号。您也可以这样做:如果有疑问,请编写一个小程序,使用PyYAML的safe_dump()转储您拥有的字符串列表,并在PyYAML所做的任何地方加上引号。