Jak wykonać wielowierszowy skrypt powłoki w Ansible

125

w tej chwili używam skryptu powłoki w ansible, który byłby znacznie bardziej czytelny, gdyby znajdował się w wielu wierszach

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

Nie wiem tylko, jak zezwolić na wielowierszowy skrypt w module powłoki Ansible

Edgar Martinez
źródło
1
Rozważ także użycie polecenia ansible „script” i użycie zewnętrznego pliku
Jason

Odpowiedzi:

273

Ansible używa składni YAML w swoich podręcznikach. YAML ma kilka operatorów bloków:

  • Jest >to operator składanego bloku. Oznacza to, że łączy wiele linii razem spacjami. Następująca składnia:

    key: >
      This text
      has multiple
      lines
    

    Byłoby przypisać wartość This text has multiple lines\ndo key.

  • |Postać jest dosłownym operator bloku. To jest prawdopodobnie to, czego potrzebujesz w przypadku wielowierszowych skryptów powłoki. Następująca składnia:

    key: |
      This text
      has multiple
      lines
    

    Byłoby przypisać wartość This text\nhas multiple\nlines\ndo key.

Możesz tego użyć dla wielowierszowych skryptów powłoki, takich jak:

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

Jest jedno zastrzeżenie: Ansible wykonuje jakąś szaloną manipulację argumentami shellpolecenia, więc chociaż powyższe będzie działać zgodnie z oczekiwaniami, poniższe nie będą:

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

Ansible faktycznie wyrenderuje ten tekst ze spacjami wiodącymi, co oznacza, że ​​powłoka nigdy nie znajdzie ciągu EOFna początku wiersza. Możesz uniknąć niekorzystnej heurystyki Ansible, używając cmdparametru w ten sposób:

- shell:
    cmd: |
      cat <<EOF
      This is a test.
      EOF
larsks
źródło
27
Fantastyczna odpowiedź
polowanie na bryana
18

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

wspomina o kontynuacjach linii YAML.

Jako przykład (próbowano z ansible 2.0.0.2):

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

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

Polecenie powłoki jest zwinięte do jednego wiersza, jak w ls --color /home

Marcello Romani
źródło
3
Tak, ale w powłoce >ma bardzo specyficzne znaczenie. Próbowałem tego i nie działało zgodnie z oczekiwaniami.
Edgar Martinez,
6
Dlatego jest tylko w pierwszej linii, a nie w kolejnych. Jak napisałem, działało dobrze dla mnie z ansible 2.0, chociaż nie wydrukowało pełnego wyjścia ls z ansible 1.9.4. Z jakiej wersji Ansible korzystałeś?
Marcello Romani
Link nie działa.
kenorb
To od 2016 roku, takie rzeczy się zdarzają.
Marcello Romani
3

Dodanie spacji przed ogranicznikiem EOF pozwala uniknąć cmd:

- shell: |
    cat <<' EOF'
    This is a test.
    EOF
Id2ndR
źródło