So erstellen Sie ein mehrzeiliges Shell-Skript in Ansible

125

Im Moment verwende ich ein Shell-Skript in Ansible, das viel besser lesbar wäre, wenn es in mehreren Zeilen wäre

- name: iterate user groups
  shell: groupmod -o -g {{ item['guid'] }} {{ item['username'] }} ....more stuff to do
  with_items: "{{ users }}"

Ich bin mir nur nicht sicher, wie ich ein mehrzeiliges Skript im Ansible-Shell-Modul zulassen soll

Edgar Martinez
quelle
1
Erwägen Sie auch, den ansible-Befehl 'script' zu verwenden und eine externe Datei zu verwenden
Jason

Antworten:

273

Ansible verwendet in seinen Playbooks die YAML-Syntax. YAML hat eine Reihe von Blockoperatoren:

  • Das >ist ein Faltblockoperator. Das heißt, es verbindet mehrere Zeilen durch Leerzeichen. Die folgende Syntax:

    key: >
      This text
      has multiple
      lines

    Würden Sie den Wert zuweisen This text has multiple lines\nzu key.

  • Das |Zeichen ist ein Literalblockoperator. Dies ist wahrscheinlich das, was Sie für mehrzeilige Shell-Skripte wünschen. Die folgende Syntax:

    key: |
      This text
      has multiple
      lines

    Würden Sie den Wert zuweisen This text\nhas multiple\nlines\nzu key.

Sie können dies für mehrzeilige Shell-Skripte wie das folgende verwenden:

- name: iterate user groups
  shell: |
    groupmod -o -g {{ item['guid'] }} {{ item['username'] }} 
    do_some_stuff_here
    and_some_other_stuff
  with_items: "{{ users }}"

Es gibt eine Einschränkung: Ansible führt einige ruckelige Manipulationen von Argumenten für den shellBefehl durch, sodass die oben genannten Funktionen im Allgemeinen wie erwartet funktionieren, die folgenden jedoch nicht:

- shell: |
    cat <<EOF
    This is a test.
    EOF

Ansible rendert diesen Text tatsächlich mit führenden Leerzeichen, was bedeutet, dass die Shell die Zeichenfolge nie EOFam Anfang einer Zeile findet. Sie können die nicht hilfreichen Heuristiken von Ansible vermeiden, indem Sie den folgenden cmdParameter verwenden:

- shell:
    cmd: |
      cat <<EOF
      This is a test.
      EOF
Larsks
quelle
27
Fantastische Antwort
Bryan Jagd
18

https://support.ansible.com/hc/en-us/articles/201957837-How-do-I-split-an-action-into-a-multi-line-format-

erwähnt die Fortsetzung der YAML-Leitung.

Als Beispiel (versucht mit ansible 2.0.0.2):

---
- hosts: all
  tasks:
    - name: multiline shell command
      shell: >
        ls --color
        /home
      register: stdout

    - name: debug output
      debug: msg={{ stdout }}

Der Shell-Befehl wird wie in einer einzelnen Zeile zusammengefasst ls --color /home

Marcello Romani
quelle
3
Ja, aber in der Shell >hat eine ganz bestimmte Bedeutung. Ich habe es versucht und es hat nicht wie erwartet funktioniert.
Edgar Martinez
6
Deshalb steht es nur in der ersten Zeile, nicht in den folgenden. Es funktionierte gut für mich mit ansible 2.0, wie ich schrieb, obwohl es nicht die vollständige ls-Ausgabe mit ansible 1.9.4 druckte. Welche Version von Ansible haben Sie verwendet?
Marcello Romani
Der Link ist tot.
Kenorb
Es ist ab 2016, diese Dinge passieren.
Marcello Romani
3

Durch Hinzufügen eines Leerzeichens vor dem EOF-Trennzeichen kann cmd vermieden werden:

- shell: |
    cat <<' EOF'
    This is a test.
    EOF
Id2ndR
quelle