如何在ansible shell模块中避免特殊字符

7

我尝试使用bash转义和双引号方法来转义下面的shell命令中的特殊字符,但两种方法都没有起作用。在ansible playbook中,正确的转义特殊字符的方法是什么?

 The offending line appears to be:

                 name: Syncing system date with htpdate failed!, Trying wget method...
                 shell: date -s "$(curl -s --head http://google.com | grep '^Date:' | sed 's/Date: //g' ) +0530"
                                                                                                ^ here

    exception type: <class 'yaml.scanner.ScannerError'>
    exception: mapping values are not allowed in this context
      in "<unicode string>", line 15, column 93

1
我认为你的意思是 shell: date -s "$(curl -s --head http://google.com | grep '^Date:' | sed 's/Date: //g') +0530" 其中s/Date/: //g 应该改成 s/Date: //g - Javier Elices
1
当然,grep x | sed 's/y/z/' 最好写成 sed -n '/x/s/y/z/p'。另请参见无用的 grep,并且 /g 标志也是无用的,除非您特别期望该行中有多个 Date: 出现。 - tripleee
@tripleee 问题在于值中的冒号后跟着一个空格“: ”。我只是想写个答案,但现在它已经关闭了!美元符号没有问题。 - tinita
如何将重复标记为错误? - tinita
那个额外的斜杠是一个打字错误,我已经纠正了,还添加了完整的错误消息,@tinita 等待您的回答。 - Shyam Jos
显示剩余2条评论
2个回答

14

这里的一个问题是冒号后跟一个空格:。通常这是映射键的指示符。

YAML不允许将嵌套映射放在同一行,例如:

foo: bar: baz

因此,YAML的设计者选择在映射值中禁止使用:,如果它在同一行上作为键出现。(也可以通过简单地忽略后续出现并将其视为常规内容来解决。)

你有几个选择。你可以将整个值放入引号中,在这种情况下这并不是一个好主意,因为你同时有单引号和双引号需要转义。

一个解决方法是在sed命令中转义空格:

shell: date -s "$(curl -s --head http://google.com | grep '^Date:' | sed 's/Date:\ //g') +0530"

一种更通用的解决方案是使用折叠块标量:

shell: >
  date -s "$(curl -s --head http://google.com | grep '^Date:' | sed 's/Date: //g') +0530"

现在你甚至可以分成几行写,因为折叠块标量将把连续的行合并成一行:

shell: >
  date -s "$(curl -s --head http://google.com
  | grep '^Date:' | sed 's/Date: //g') +0530"
第二个问题是,正如Javier所提到的,sed表达式 s / Date /:// g 。您可能想要 s / Date:// g 。还请查看@tripleee的建议如何改进您的命令。

2
非常感谢,折叠块标量解决了我的问题。 - Shyam Jos
谢谢,我的问题已经通过折叠块得到解决。 - Jean-Marc Amon

-1

请注意转义字符是\而不是/

编辑

你的问题与转义字符无关,而是由于你的sed表达式多了一个/

sed 's/Date: ///g'

应该写成 sed 's/foo/bar/g'

在你的情况下,应该使用sed 's/Date: //g'


1
我认为你的回复应该是一条评论。它并没有提出问题的答案。此外,我没有看到任何需要转义的内容。他在大引号中使用了双引号,然后在其中使用了单引号。 - Javier Elices
我猜回答者不熟悉 sed 命令,并且误认为 sed 's/foo/bar/' 中的斜杠分隔符应该是反斜杠。 - tripleee
@alvaro-nino 那个额外的斜杠是一个打字错误,现在已经更正了。 - Shyam Jos

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