Как сделать многострочный сценарий оболочки в Ansible

126

прямо сейчас я использую сценарий оболочки в доступе, который был бы намного более читаемым, если бы он был на нескольких строках

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

Просто не уверен, как разрешить многострочный скрипт в модуле оболочки Ansible

Эдгар Мартинес
источник
1
Также рассмотрите возможность использования команды ansible 'script и используйте внешний файл
Джейсон

Ответы:

274

Ansible использует синтаксис YAML в своих сборниках. YAML имеет ряд блочных операторов:

  • Оператор >складного блока. То есть он объединяет несколько строк пробелами. Следующий синтаксис:

    key: >
      This text
      has multiple
      lines
    

    Назначить ли значение This text has multiple lines\nдля key.

  • Этот |символ является буквальным оператором блока. Вероятно, это то, что вам нужно для многострочных сценариев оболочки. Следующий синтаксис:

    key: |
      This text
      has multiple
      lines
    

    Назначить ли значение This text\nhas multiple\nlines\nдля key.

Вы можете использовать это для многострочных сценариев оболочки, например:

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

Есть одно предостережение: Ansible выполняет некоторую резкую манипуляцию с аргументами shellкоманды, поэтому, хотя приведенное выше, как правило, будет работать должным образом , следующее не будет:

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

Ansible фактически отобразит этот текст с ведущими пробелами, что означает, что оболочка никогда не найдет строку EOFв начале строки. Вы можете избежать бесполезной эвристики Ansible, используя следующий cmdпараметр:

- shell:
    cmd: |
      cat <<EOF
      This is a test.
      EOF
larsks
источник
27
Фантастический ответ
брайан хант
18

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

упоминает продолжения строки YAML.

В качестве примера (пробовал с ansible 2.0.0.2):

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

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

Команда оболочки сворачивается в одну строку, как в ls --color /home

Марчелло Романи
источник
3
Ага, но в оболочке >есть очень конкретное значение. Я попробовал это, и это не сработало, как ожидалось.
Эдгар Мартинес
6
Поэтому он находится только в первой строке, а не в последующих. Как я уже писал, у меня он работал нормально с ansible 2.0, хотя он не распечатал полный вывод ls с ansible 1.9.4. Какую версию Ansible вы использовали?
Марчелло Романи
Ссылка мертвая.
kenorb
Это с 2016 года такое случается.
Марчелло Романи
3

Добавление пробела перед разделителем EOF позволяет избежать cmd:

- shell: |
    cat <<' EOF'
    This is a test.
    EOF
Id2ndR
источник