YAML 无效 - 可能是引号问题

YAML invalid - maybe quote marks issue

我从 Gitlab CI/CD 管道获取错误信息:yaml invalid。问题是由 .gitlab-ci.yml 脚本的第五行引起的:

   - 'ssh deployer@gitadam.ga \'rm /var/www/html/hosts/production/current/temp__*\''

脚本部分

script:
    - 'pwd'
    - 'whoami'
    - 'ls temp__*'
    - 'ssh deployer@gitadam.ga \'rm /var/www/html/hosts/production/current/temp__*\''
    - 'if ls temp__* 1> /dev/null 2>&1; then for file in temp__*; do scp $file deployer@gitadam.ga:/var/www/html/hosts/production/current/; done; fi'

如何修复线路?

您应该在不带引号的情况下自己尝试一次,然后再张贴在这里。

但是,是的,似乎是因为那个。

script:
  - pwd
  - whoami
  - ls temp__*
  - ssh deployer@gitadam.ga 'rm /var/www/html/hosts/production/current/temp__*'
  - if ls temp__* 1> /dev/null 2>&1; then for file in temp__*; do scp $file deployer@gitadam.ga:/var/www/html/hosts/production/current/; done; fi

GitLab 还为其 ci 语法提供了一个内置的 linter

你可以只留下开始和结束的单引号,不需要使用暴力将它们全部删除。 这可能会导致其他错误(虽然不是您的情况),并且您的情况不足以获得您想要的结果。¹

真正的问题是您试图以错误的方式在单引号标量中转义单引号。在单引号标量中唯一可以并且需要转义的字符是单引号。所以这不能像您那样通过使用反斜杠来完成,因为反斜杠也需要在单引号标量中转义。

要在单引号标量中转义单引号,您需要 double/repeat it

YAML specification的写法略有不同,大意相同:

The single-quoted style is specified by surrounding “'” indicators. Therefore, within a single-quoted scalar, such characters need to be repeated. This is the only form of escaping performed in single-quoted scalars. In particular, the “\” and “"” characters may be freely used.

所以要更改第 5 行,只需将两个反斜杠更改为单引号即可:

script:
    - 'pwd'
    - 'whoami'
    - 'ls temp__*'
    - 'ssh deployer@gitadam.ga ''rm /var/www/html/hosts/production/current/temp__*'''
    - 'if ls temp__* 1> /dev/null 2>&1; then for file in temp__*; do scp $file deployer@gitadam.ga:/var/www/html/hosts/production/current/; done; fi'

在 YAML 中的 double 引用标量中,您可以使用反斜杠转义以获得双引号,但也可以使用所有类型的特殊字符,或促进 YAML 功能。然而single quotes are not escapable that way。如果使用双引号,第五行需要删除反斜杠:

    - "ssh deployer@gitadam.ga 'rm /var/www/html/hosts/production/current/temp__*'"

保留引号有多种原因。如果您的任何标量都以特殊(对于 YAML)字符开头,则您需要引用。标量以字母 (A-Za-z) 开头是不够的:如果标量碰巧有特殊序列,例如注释开始序列 (space + octothorpe) 或值指示符 (冒号 + space ) 序列嵌入,那么你也必须使用引号。

使用单引号比不使用它们更安全,使用它们时您唯一需要知道的就是如何转义它们。它们有时可能是多余的,但它们是在 YAML 中定义标量字符串的最简单方法(关于您需要考虑的异常数量)。


¹如果删除前导单引号和尾随单引号,则还需要像第 5 行那样删除反斜杠。

²这里的"it"指的是单引号,当然不是整个标量。