YAML 无效 - 可能是引号问题

trz*_*czy 2 yaml quoting gitlab-ci

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

   - 'ssh deployer@gitadam.ga \'rm /var/www/html/hosts/production/current/temp__*\''
Run Code Online (Sandbox Code Playgroud)

脚本部分

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'
Run Code Online (Sandbox Code Playgroud)

线怎么修?

Ant*_*hon 5

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

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

要在单引号标量中转义单引号,您需要将其加倍/重复。²

YAML 规范中,措辞略有不同,但效果相同:

单引号样式由周围的“'”指示符指定。因此,在单引号标量中,此类字符需要重复。这是在单引号标量中执行的唯一转义形式。特别是,“\”和“””字符可以自由使用。

因此,要更改第 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'
Run Code Online (Sandbox Code Playgroud)

在YAML 中的引号标量中,您可以使用反斜杠转义以获得双引号,但也可以使用所有类型的特殊字符,或促进 YAML 功能。然而,单引号不能这样转义。如果您使用双引号,则需要删除第 5 行的反斜杠:

    - "ssh deployer@gitadam.ga 'rm /var/www/html/hosts/production/current/temp__*'"
Run Code Online (Sandbox Code Playgroud)

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

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


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

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