How to escape backslash and double quote in Ansibl

2019-01-25 20:54发布

I'm very new to Ansible (2.x) and I am having trouble using the script module and passing parameters with double quotes and backslashes.

Assuming we have a set variable {{foo}} which contains a string "foo", I have a task like this:

set_fact:
   arg: \(-name "{{foo}}" \)
name: call shell module
script: path/somescript.sh "{{arg}}"

My script needs the following structure of the argument in order to work:

\(-name "foo" \)

I tried several things such as:

arg: \(-name \""{{foo}}"\" \)           result: \\(-name \"foo\" \\)

arg: '\(-name \""{{foo}}"\" \)'         result: \\(-name \"foo\" \\)

arg: \\(-name \""{{foo}}"\" \\)           result: \\(-name \"foo\" \\)

Is it possible to escape backslashes and double quotes in Ansible?

标签: ansible
2条回答
萌系小妹纸
2楼-- · 2019-01-25 21:14

You're very close. I think you want to set a variable, not a fact, and I would suggest you use the shell module instead of the script module. shell is more forgiving when it comes to escaping and quoting complex shell commands.

---
- hosts: localhost
  vars:
    foo: test.yml
    arg: \( -name "{{ foo }}" \)
  tasks:
    - debug: var=arg
    - shell: find . {{ arg }}
      register: find
    - debug: var=find.stdout_lines

And the output:

$ ansible-playbook test.yml 

PLAY [localhost] ***************************************************************

TASK [debug] *******************************************************************
ok: [localhost] => {
    "arg": "\\( -name \"test.yml\" \\)"
}

TASK [command] *****************************************************************
changed: [localhost]

TASK [debug] *******************************************************************
ok: [localhost] => {
    "find.stdout_lines": [
        "./test.yml"
    ]
}

PLAY RECAP *********************************************************************
localhost                  : ok=3    changed=1    unreachable=0    failed=0   
查看更多
姐就是有狂的资本
3楼-- · 2019-01-25 21:25

Don't be confused by the fact that ansible-playbook prints debug messages in JSON encoded form, so some characters are escaped.

set_fact:
  arg: \(-name "{{foo}}" \)

You have correct syntax. This will set arg to \(-name "bar" \) if foo's value is bar.
But the debug message in this case will look like this:

ok: [localhost] => {
    "arg": "\\(-name \"bar\" \\)"
}

Note that special characters for JSON (" and \) are escaped.

But there may be some issues with passing this as parameter.
If call you script, like this

script: path/somescript.sh "{{arg}}"

Parameters string will look like this "\(-name "bar" \)" which is actually 3 concatenated strings in bash: \(-name+bar+\), so you will loose double quotes around the bar.

If you want to preserve those double quotes, use:

script: path/somescript.sh '{{arg}}'
查看更多
登录 后发表回答