如何在Ansible中做多行shell脚本

时间:2022-05-03 19:09:19

right now I am using a shell script in ansible that would be much more readable if it was on multiple lines

现在我在ansible中使用一个shell脚本,如果它在多行上会更加可读

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

Just not sure how to allow multiline script in Ansible shell module

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

2 个解决方案

#1


108  

Ansible uses YAML syntax in its playbooks. YAML has a number of block operators:

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

  • The > is a folding block operator. That is, it joins multiple lines together by spaces. The following syntax:

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

    key: >
      This text
      has multiple
      lines
    

    Would assign the value This text has multiple lines\n to key.

    将赋值该文本有多行\ n到键。

  • The | character is a literal block operator. This is probably what you want for multi-line shell scripts. The following syntax:

    | character是一个文字块运算符。这可能是您想要的多行shell脚本。以下语法:

    key: |
      This text
      has multiple
      lines
    

    Would assign the value This text\nhas multiple\nlines\n to key.

    将值赋值为this text \ n有多个\ nlines \ n到key。

You can use this for multiline shell scripts like this:

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

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

There is one caveat: Ansible does some janky manipulation of arguments to the shell command, so while the above will generally work as expected, the following won't:

有一点需要注意:Ansible对shell命令的参数进行了一些简单的操作,因此虽然上面的内容通常会按预期工作,但以下内容不会:

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

Ansible will actually render that text with leading spaces, which means the shell will never find the string EOF at the beginning of a line. You can avoid Ansible's unhelpful heuristics by using the cmd parameter like this:

Ansible实际上会使用前导空格渲染该文本,这意味着shell永远不会在行的开头找到字符串EOF。您可以使用cmd参数来避免Ansible的无用启发式,如下所示:

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

#2


8  

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

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

mentions YAML line continuations.

提到YAML线延续。

As an example (tried with ansible 2.0.0.2):

作为一个例子(尝试使用ansible 2.0.0.2):

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

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

The shell command is collapsed into a single line, as in ls --color /home

shell命令折叠成一行,如ls --color / home

#1


108  

Ansible uses YAML syntax in its playbooks. YAML has a number of block operators:

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

  • The > is a folding block operator. That is, it joins multiple lines together by spaces. The following syntax:

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

    key: >
      This text
      has multiple
      lines
    

    Would assign the value This text has multiple lines\n to key.

    将赋值该文本有多行\ n到键。

  • The | character is a literal block operator. This is probably what you want for multi-line shell scripts. The following syntax:

    | character是一个文字块运算符。这可能是您想要的多行shell脚本。以下语法:

    key: |
      This text
      has multiple
      lines
    

    Would assign the value This text\nhas multiple\nlines\n to key.

    将值赋值为this text \ n有多个\ nlines \ n到key。

You can use this for multiline shell scripts like this:

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

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

There is one caveat: Ansible does some janky manipulation of arguments to the shell command, so while the above will generally work as expected, the following won't:

有一点需要注意:Ansible对shell命令的参数进行了一些简单的操作,因此虽然上面的内容通常会按预期工作,但以下内容不会:

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

Ansible will actually render that text with leading spaces, which means the shell will never find the string EOF at the beginning of a line. You can avoid Ansible's unhelpful heuristics by using the cmd parameter like this:

Ansible实际上会使用前导空格渲染该文本,这意味着shell永远不会在行的开头找到字符串EOF。您可以使用cmd参数来避免Ansible的无用启发式,如下所示:

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

#2


8  

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

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

mentions YAML line continuations.

提到YAML线延续。

As an example (tried with ansible 2.0.0.2):

作为一个例子(尝试使用ansible 2.0.0.2):

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

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

The shell command is collapsed into a single line, as in ls --color /home

shell命令折叠成一行,如ls --color / home