web-dev-qa-db-fra.com

Comment éviter les barres obliques inverses et les guillemets dans Ansible (module de script)

Je suis très nouveau dans Ansible (2.x) et j'ai des difficultés à utiliser le module de script et à transmettre des paramètres avec des guillemets doubles et des barres obliques inverses.

En supposant que nous ayons une variable d'ensemble {{foo}} qui contient la chaîne "foo", j'ai une tâche comme celle-ci:

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

Mon script nécessite la structure suivante de l'argument pour fonctionner:

\(-name "foo" \)

J'ai essayé plusieurs choses telles que:

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

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

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

Est-il possible d'échapper aux barres obliques inverses et aux guillemets dans Ansible?

5
Vetemi

Ne soyez pas dérouté par le fait que ansible-playbook imprime les messages de débogage sous forme codée JSON, de sorte que certains caractères sont échappés.

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

Vous avez la syntaxe correcte. Ceci définira arg sur \(-name "bar" \) si la valeur de foo est bar.
Mais le message de débogage dans ce cas ressemblera à ceci:

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

Notez que les caractères spéciaux pour JSON (" et \) sont protégés.

Cependant, le fait de passer cela en paramètre peut poser problème.
Si vous appelez script, comme ceci

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

Les paramètres de chaîne ressembleront à ceci "\(-name "bar" \)" qui correspond en fait à 3 chaînes concaténées dans bash: \(-name + bar + \), de sorte que vous perdrez les guillemets doubles autour de bar .

Si vous souhaitez conserver ces guillemets, utilisez:

script: path/somescript.sh '{{arg}}'
5
Konstantin Suvorov

Tu es très proche. Je pense que vous souhaitez définir une variable, pas un fait, et je vous suggère d'utiliser le module Shell au lieu du module script. Shell est plus indulgent lorsqu'il s'agit d'échapper et de citer des commandes Shell complexes. 

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

Et la sortie:

$ 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   
1
mwp