How to escape double and single quotes in YAML within the same string

房东的猫 提交于 2020-07-17 03:25:26

问题


I need to properly escape single and double quotes in an ansible playbook in order to set the environment variable. None of this works:

  - name: Set environment variable
    command: >
      export EXTRA_CONFIG=“'”{"client": {"subscriptions": ["DIND-Worker"], "cluster": "internal"}}“'”

  - name: Set environment variable
    command: >
      export EXTRA_CONFIG=''{"client": {"subscriptions": ["DIND-Worker"], "cluster": "internal"}}''

  - name: Set environment variable
    command: >
      export EXTRA_CONFIG=''{\"client\": {\"subscriptions\": [\"DIND-Worker\"], \"cluster\": \"internal\"}}''

Looked at this:

http://yaml.org/spec/current.html#id2532720

https://github.com/dotmaster/toYaml/issues/1

The error message I get is:

fatal: [ip.address]: FAILED! => {"changed": false, "cmd": "export 'EXTRA_CONFIG={\"client\":' '{\"subscriptions\":' '[\"DIND-Worker\"],' '\"cluster\":' '\"internal\"}}'", "failed": true, "msg": "[Errno 2] No such file or directory", "rc": 2}

回答1:


> starts a block scalar, in which you do not need to escape anything at all (and there are no escape sequences processed). So assuming you want single quotes around your JSON-like value, just do:

  - name: Set environment variable
    command: >
      export EXTRA_CONFIG='{"client": {"subscriptions": ["DIND-Worker"], "cluster": "internal"}}'

Edit: Also be aware that a folded scalar by default includes a trailing newline character. If you do not want to have this, just use >- instead of >.




回答2:


You are using folded style scalars (introduced by >) and according to the YAML 1.2 specification you cannot escape characters:

Folded scalars:

The folded style is denoted by the “>” indicator. It is similar to the literal style; however, folded scalars are subject to line folding.

And the relevant text wrt escaping in literal style scalars.

Inside literal scalars, all (indented) characters are considered to be content, including white space characters. Note that all line break characters are normalized. In addition, empty lines are not folded, though final line breaks and trailing empty lines are chomped.

From your example it is unclear what you really want to do. You should probably drop folding style in favour of double quoted style:

The double-quoted style is specified by surrounding “"” indicators. This is the only style capable of expressing arbitrary strings, by using “\” escape sequences. This comes at the cost of having to escape the “\” and “"” characters.

or single quoted style:

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. This restricts single-quoted scalars to printable characters. In addition, it is only possible to break a long single-quoted line where a space character is surrounded by non-spaces.

So you should first decide what the output should be exactly, then if you need to escape any characters with backslash. If you don't you can just use folded style without any escaping, or single quoted style by escaping the ', or double quoted style by escaping " and any \. If you need \ escaping double quoted style is your only option.




回答3:


I don't think this has anything to do with escaping. From the docs for command:

The command module takes the command name followed by a list of space-delimited arguments. The given command will be executed on all selected nodes. It will not be processed through the shell, so variables like $HOME and operations like "<", ">", "|", and "&" will not work (use the shell module if you need these features).

The command you're trying to run, export, isn't an executable; it's a shell builtin. It makes sense that if Ansible isn't running the command through a shell that shell builtins aren't available, ergo "No such file or directory."

Like the docs say, you could use shell instead of command, but I'm not sure this is a solution, because Ansible probably doesn't run subsequent commands in the same shell, so any environment variables you set previously will be absent. See the answers to this question for some options that are more likely to work: How to set linux environment variables with ansible



来源:https://stackoverflow.com/questions/37427498/how-to-escape-double-and-single-quotes-in-yaml-within-the-same-string

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!