如何在Ansible中执行多行Shell脚本


125

现在我正在使用ansible的shell脚本,如果它在多行上会更易读

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

只是不确定如何在Ansible Shell模块中允许多行脚本


1
还可以考虑使用ansible'script'命令并使用外部文件
Jason

Answers:


273

Ansible在其剧本中使用YAML语法。YAML具有许多块运算符:

  • >是一折叠块运算符。也就是说,它通过空格将多条线连接在一起。语法如下:

    key: >
      This text
      has multiple
      lines
    

    会将值分配This text has multiple lines\nkey

  • |字符是文字​​块运算符。这可能是多行shell脚本所需要的。语法如下:

    key: |
      This text
      has multiple
      lines
    

    会将值分配This text\nhas multiple\nlines\nkey

您可以将其用于多行shell脚本,如下所示:

- 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实际上将使用前导空格来呈现该文本,这意味着Shell永远不会EOF在行首找到字符串。您可以使用以下cmd参数来避免Ansible的无用启发式:

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

27
很棒的答案
布莱恩·亨特(Bryan hunt)

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 }}

shell命令折叠为一行,如下所示: ls --color /home


3
是的,但是在外壳中>有非常具体的含义。我试过了,它没有按预期工作。
Edgar Martinez

6
这就是为什么它只是在第一行,而不是在随后的行。如我所写,它对ansible 2.0的工作对我来说很好,尽管它并没有打印出对ansible 1.9.4的完整ls输出。您使用了哪个版本的Ansible?
Marcello Romani

链接已死。
kenorb

从2016年开始,这些事情发生了。
Marcello Romani

3

在EOF分隔符之前添加一个空格可以避免使用cmd:

- shell: |
    cat <<' EOF'
    This is a test.
    EOF
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.