Quotes in ansible lineinfile

2019-02-12 00:12发布

问题:

When I use lineinfile in ansible it is not writing ', " characters lineinfile: 'dest=/home/xyz state=present line="CACHES="default""'

it is giving CACHES=default but the desired output is CACHES="default"

How to achieve this?

回答1:

it appears you can escape the quotes:

- lineinfile: dest=/tmp/xyz state=present line="CACHES=\"default\""

That gives this output:

$ cat /tmp/xyz
CACHES="default"

You don't need to escape single quotes that are inside double quotes:

- lineinfile: dest=/tmp/xyz state=present line="CACHES=\"default\" foo='x'"
cat /tmp/xyz
CACHES="default" foo='x'

source: YAML specification, stackoverflow answer



回答2:

Ansible 1.9.2 contains a bug (https://github.com/ansible/ansible/issues/10864), which fails to insert escaped double quotes at the beginning or end of the line.

E.g., the following

- name: /home/core/linetest
  lineinfile: dest="/home/core/linetest" line="\"ma\"ok\"in\""

will result in missing first and last double-quotes (even though you escaped it).

#/home/core/linetest
ma"ok"in

To compensate for this bug, you could add a PREFIX to the starting and ending double quotes, and subsequently removing it.

- name: PREFIX first and last escaped double quotes with 'KUCF'
  lineinfile: dest="/home/core/linetest" line="KUCF\"main\"KUCF"

- name: remove 'KUCF' PREFIX
  replace: dest="/home/core/linetest" regexp="KUCF" replace=""

which should give you

#/home/core/linetest
"main"

Make sure that your chosen PREFIX will never be used in the context of the destination file. In general, the longer and more random the PREFIX, the less likely it will clash with existing content in your destination file.

Alternatively, you could upgrade your Ansible to the latest branch.



回答3:

If the content to be substituted is in a variable higher up in the playbook, it seems that you need to escape the escape characters instead of the quotes, something like this

---
- hosts: tomcat

  vars:
    classpath: "CLASSPATH=\\\"$CATALINA_HOME/bin/foo.jar\\\""

  tasks:

    - lineinfile: dest="/tomcat/bin/setenv.sh" line="{{ classpath }}" state=present

ends up with a line like this in the resulting file

CLASSPATH="$CATALINA_HOME/bin/foo.jar"


回答4:

Just a follow up to this, above examples did not work for me when trying to create a batch file on a windows box using win_lineinfile. The file was being created, the line was being inserted, but the quotes and backslashes were formatted terribly. This was with ansible 2.4. What I finally ended up doing per a co workers suggestion was some inline jinja templating;

- name: insert our batch file contents
  win_copy:
    dest: C:\QAAutomation\files\posauto.bat
    force: yes
    content: |
      {% raw %}"C:\Program Files (x86)\NUnit 2.6.3\bin\nunit-console.exe" "C:\QAAutomation\files\1POS Automation\Application Files\Bin\Automation.dll" > "c:\QAAutomation\results\nunit-console-output.txt" {% endraw %}