Come eseguire script di shell multilinea in Ansible


125

in questo momento sto usando uno script di shell in ansible che sarebbe molto più leggibile se fosse su più righe

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

Non sono sicuro di come consentire lo script multilinea nel modulo della shell Ansible


1
Considera anche l'utilizzo del comando ansible "script" e utilizza un file esterno
Jason

Risposte:


273

Ansible utilizza la sintassi YAML nei suoi playbook. YAML ha una serie di operatori di blocco:

  • La >è un operatore di blocco pieghevole. Cioè, unisce più linee insieme da spazi. La seguente sintassi:

    key: >
      This text
      has multiple
      lines

    Assegnerebbe il valore This text has multiple lines\na key.

  • Il |carattere è un operatore di blocco letterale. Questo è probabilmente quello che vuoi per gli script di shell multilinea. La seguente sintassi:

    key: |
      This text
      has multiple
      lines

    Assegnerebbe il valore This text\nhas multiple\nlines\na key.

Puoi usarlo per script shell multilinea come questo:

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

C'è un avvertimento: Ansible esegue alcune manipolazioni janky degli argomenti del shellcomando, quindi mentre quanto sopra funzionerà generalmente come previsto, quanto segue non lo farà:

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

Ansible effettivamente renderà quel testo con spazi EOFiniziali , il che significa che la shell non troverà mai la stringa all'inizio di una riga. Puoi evitare le inutili euristiche di Ansible utilizzando il cmdparametro in questo modo:

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

27
Risposta fantastica
bryan hunt

18

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

menziona le continuazioni della linea YAML.

Ad esempio (provato con ansible 2.0.0.2):

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

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

Il comando della shell è compresso in una singola riga, come in ls --color /home


3
Sì, ma in shell >ha un significato ben preciso. Ho provato questo e non ha funzionato come previsto.
Edgar Martinez

6
Ecco perché è solo nella prima riga, non in quelle successive. Ha funzionato bene per me con ansible 2.0 come ho scritto, anche se non ha stampato l'output ls completo con ansible 1.9.4. Quale versione di Ansible hai usato?
Marcello Romani

Il collegamento è morto.
kenorb

È del 2016, queste cose accadono.
Marcello Romani

3

L'aggiunta di uno spazio prima del delimitatore EOF consente di evitare cmd:

- shell: |
    cat <<' EOF'
    This is a test.
    EOF
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.