
转载说明:如果您喜欢这篇文章并打算转载它,请私信作者取得授权。感谢您喜爱本文,请文明转载,谢谢。
在《Ansible-playbook的逻辑控制 ①》中,梳理了逻辑控制when的使用场景,本文则继续梳理学习loop与block块的使用场景。
when:条件判断语句,类似于shell中的if;
loop:循环语句,类似于 shell中的while;
block:把几个任务组成一个代码块,以便于针对一组操作的异常进行处理等操作。
SRE成长记,公众号:SRE成长记Ansible-playbook的逻辑控制 ①
Loop用法
1. 简单的标准循环
在Ansible-playbook的逻辑控制 ①中,when与with_items共用判断数字的例子还可以这样写:
[root@test101 ansible-test]# cat loop1.yaml 
---
- hosts: test
  gather_facts: no
  tasks:
    - name: test of loop
      debug:
        msg: item is {{ item }}
      ##with_items: [ 0, 3, 5, 8, 10, 26 ]  #原写法
      #loop: [ 0, 3, 5, 8, 10, 26 ]  #写法一
      loop:   #写法二
        - 0
        - 3
        - 5
        - 8
        - 10
        - 26
      when: item > 6
[root@test101 ansible-test]#使用举例—使用loop批量创建一组文件:
[root@test101 ansible-test]# cat loop2.yaml 
---
- hosts: test
  gather_facts: no
  tasks:
    - name: test of loop
      file: path=/tmp/sre{{ item }}.txt state=touch
      #loop: [ 1, 2, 3 ]  #写法一
      loop: #写法二
        - 1
        - 2
        - 3
[root@test101 ansible-test]# 执行结果:

如果文件名的后缀、文件名都不统一,可以将要创建的文件列举出来,这种场景适用于创建少量文件,如果几十、上千百,就不适用了:
[root@test101 ansible-test]# cat loop3.yaml 
---
- hosts: test
  gather_facts: no
  tasks:
    - name: test of loop
      file: path=/tmp/sre{{ item }} state=touch
      #loop: [ sre.txt, test.yaml, file.sh ]  #写法一
      loop: #写法二
        - sre.txt
        - test.yaml
        - file.sh
[root@test101 ansible-test]#执行结果:

2. 与变量一起使用
如果在变量文件或vars区域定义了一组列表变量,也可以使用loop来循环变量。
如上面的创建文件的例子可以这样写:
[root@test101 ansible-test]# cat loop4.yaml 
---
- hosts: test
  gather_facts: no
  vars:
    files: [ "sre.txt", "test.yaml", "file.sh" ]
  tasks:
    - name: test of loop
      file: path=/tmp/sre{{ item }} state=touch
      #with_items: "{{files}}"   #写法一
      loop: "{{files}}"   #写法二
[root@test101 ansible-test]#执行结果:

3. 嵌套循环
loop循环也可以嵌套,可以用[]和 . 访问内层和外层的循环。
例如:
[root@test101 ansible-test]# cat loop5.yaml 
---
- hosts: test
  gather_facts: no
  tasks:
    - name: test of loop
      debug:
        #msg: "my hostname is {{ item[0] }},and my ip is {{ item[1] }}"  #写法一
        msg: "my hostname is {{ item.0 }},and my ip is {{ item.1 }}"   #写法二
      with_nested:
        - [ 'test102', 'test103' ]
        - [ '10.0.0.102', '10.0.0.103' ]
  tags:
    loops
[root@test101 ansible-test]#执行结果:

4. 哈希表循环
除了嵌套循环,还可以对hash表进行循环。
例如,使用循环批量创建2个用户并执行需要所在的组:
[root@test101 ansible-test]# cat loop6.yaml 
---
- hosts: test
  gather_facts: no
  tasks:
    - name: test of loop
      user: name={{ item.name }} state=present groups={{ item.groups }}
      #with_items:
      loop:
      - { name: 'sre1', groups: 'sre' }  # group需要是已存在group
      - { name: 'sre2', groups: 'root' }
[root@test101 ansible-test]# 执行结果:

再例如,打印一组服务器节点信息:
[root@test101 ansible-test]# cat loop7.yaml 
---
- hosts: test
  gather_facts: no
  vars:
    servers:
      server102:
        hostname: test102
        ip: 10.0.0.102
      server103:
        hostname: test103
        ip: 10.0.0.103
  tasks:
    - name: test of loop
      debug: 
        msg: "servers {{ item.key }} is {{ item.value.hostname }} ({{ item.value.ip }})"
      #with_dict: "{{ servers }}" #写法一
      loop: "{{ lookup('dict',servers)}}" #写法二
[root@test101 ansible-test]#执行结果:

5. 对文件列表使用循环
[root@test101 ansible-test]# cat loop8.yaml
---
- name: test of loop
  hosts: test
  gather_facts: false  # We don't need to gather facts
  tasks:
    - name: Find .txt files in /tmp directory
      find:
        paths: /tmp
        patterns: "*.txt"
      register: txt_files
    - name: show all .txt files
      debug:
        msg: "{{ item.path }}"
      loop: "{{ txt_files.files }}"
      when: txt_files.matched > 0
[root@test101 ansible-test]#执行效果:

Block块
在ansible中,还可以使用"block"关键字将多个任务整合成一个"块",这个"块"将被当做一个整体。可以根据不同的条件,执行一段语句。
例如,通过block语句判断docker服务是否存在:
[root@test101 ansible-test]# cat block1.yaml
---
- name: test of block
  hosts: test
  become: yes  # Ensure privilege escalation if required
  tasks:
    - name: Check if docker is installed
      shell: systemctl is-active docker
      register: service_status
      ignore_errors: yes  # Ignore errors if doker doesn't exist
    - name: Stop docker if it's running
      block:
        - name: Stop the docker
          systemd:
            name: docker
            state: stopped
          when: service_status.rc == 0  # Only stop if docker is active
        - name: Disable docker
          systemd:
            name: docker
            enabled: no
          when: service_status.rc == 0  # Only disable if docker was active
      when: service_status.rc == 0  # Only execute block if docker is installed and running
[root@test101 ansible-test]#执行效果:

(END)




![[数据集][目标检测]游泳者溺水检测数据集VOC+YOLO格式8275张4类别](https://i-blog.csdnimg.cn/direct/b5b325b3696d47c5a7c5b07a407b8d66.png)














