已归录

简单的 loop 循环(simple loops)

# cat demo.yml 
---
- name: demo of simple loops 
  hosts: web
  gather_facts: no
  tasks:
  - name: services are running
    service:
      name: "{{ item }}"
      state: started
    loop:
      - sshd
      - crond

loop 使用的 list 也可以由变量提供

# cat demo.yml 
---
- name: demo of simple loops 
  hosts: web
  gather_facts: no
  vars:
    services_names:
      - sshd
      - crond
  tasks:
  - name: services are running
    service:
      name: "{{ item }}"
      state: started
    loop:
      "{{ services_names }}"

loop 列表可以是字典(loops over a list of hashes or dictionaries)

# cat demo.yml 
---
- name: demo of loops 
  hosts: web
  gather_facts: no
  tasks:
  - name: services are running
    service:
      name: "{{ item.name }}"
      state: "{{ item.state }}"
    loop:
      - name: sshd
        state: started
      - name: crond
        state: started

这儿 loop 的另一种写法是:

    loop:
      - { name: "sshd", state: "started" }
      - { name: "crond", state: "started" }

loop 使用的字典也可以由变量提供(教材未提)

---
- hosts: web
  vars:
    services:
      service1:
        name: sshd
        state: started
      service2:
        name: crond
        state: started
  tasks:
  - name: services are running 
    service:
      name: "{{ item.value.name }}"
      state: "{{ item.value.state }}"
    loop: "{{ services|dict2items }}"

以前老版本不是用的 loop 关键字,而是 with_items 关键字,用法一样。从 Ansible 2.5 开始,推荐使用 loop。

loop 与 register 结合使用

# cat demo.yml 
---
- hosts: web
  vars:
    services:
      service1:
        name: sshd
        state: started
      service2:
        name: crond
        state: started
  tasks:
  - name: services are running 
    shell: systemctl is-active "{{ item.value.name }}"
    loop: "{{ services|dict2items }}"
    register: cy_results
    ignore_errors: yes

  - name: show value of var
    debug:
      var: cy_results

注意两点:

  1. 一定要有 ignore_errors: yes,否则,如果服务没有运行将报错,就不能到 debug 显示注册变量的值
  2. 不用担心变量会被 loop 覆盖,它会把多次循环的结果都记录在注册变量['results']中(打印显示一下就明白了)
    在该例中,如果想取 sshd 服务的状态:cy_results['results'][0]['rc'] 或者 cy_results['results'][0]['stdout_lines'][0]

现在,修改一下剧本,如果服务不是 active,则启动它:

# cat demo.yml 
---
- hosts: web
  vars:
    services:
      service1:
        name: sshd
        state: started
      service2:
        name: crond
        state: started
  tasks:
  - name: services are running 
    shell: systemctl is-active "{{ item.value.name }}"
    loop: "{{ services|dict2items }}"
    register: cy_results
    ignore_errors: yes

下面的取值感觉很复杂,其实很简单,在上面的输出中一层一层往下找就行了:

  - name: start service if not started
    service: 
          name: "{{ item.item.value.name }}"
          state: started
    when: item.rc != 0
    loop: "{{ cy_results['results'] }}"
-- By 许望(RHCA、OCM、VCP)
最后修改:2020 年 06 月 28 日 09 : 41 AM
如果觉得我的文章对你有用,请随意赞赏