webentwicklung-frage-antwort-db.com.de

Wie man Backslash und Anführungszeichen in Ansible (Skriptmodul)

Ansible (2.x) ist sehr neu und ich habe Probleme beim Verwenden des Skriptmoduls und beim Übergeben von Parametern mit Anführungszeichen und umgekehrten Schrägstrichen.

Angenommen, wir haben eine gesetzte Variable {{foo}}, die eine Zeichenfolge "foo" enthält, habe ich eine Aufgabe wie diese:

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

Mein Skript benötigt die folgende Struktur des Arguments, um funktionieren zu können:

\(-name "foo" \)

Ich habe verschiedene Dinge ausprobiert wie:

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

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

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

Kann man in Ansible Backslashes und Anführungszeichen vermeiden?

5
Vetemi

Lassen Sie sich nicht durch die Tatsache verwirren, dass das Ansible-Playbook Debug-Meldungen in JSON-codierter Form ausgibt, sodass einige Zeichen mit Escapezeichen versehen werden.

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

Sie haben die richtige Syntax. Dies setzt arg auf \(-name "bar" \), wenn der Wert von foobar ist.
Die Debug-Nachricht sieht in diesem Fall jedoch so aus:

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

Beachten Sie, dass Sonderzeichen für JSON (" und \) mit Escapezeichen versehen werden.

Es kann jedoch Probleme geben, wenn Sie dies als Parameter übergeben.
Wenn Sie Ihr Skript aufrufen, so

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

Die Parameterzeichenfolge sieht wie folgt aus "\(-name "bar" \)", wobei es sich tatsächlich um drei verkettete Zeichenfolgen in der Bash handelt: \(-name + bar + \), so dass Sie doppelte Anführungszeichen um die bar setzen.

Wenn Sie diese doppelten Anführungszeichen beibehalten möchten, verwenden Sie:

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

Du bist sehr nahe. Ich denke, Sie möchten eine Variable und keine Tatsache festlegen, und ich würde vorschlagen, dass Sie das Modul Shell anstelle des Moduls script verwenden. Shell ist verzeihender, wenn es darum geht, komplexe Shell-Befehle zu umgehen und zu zitieren. 

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

Und die Ausgabe:

$ 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