Playbook控制语句

本章主要介绍 playbook中的控制语句。
  • 使用When判断语句
  • block-rescue判断
  • 循环语句

目录

1.判断语句When

1.1 When判断中>、<、!=的使用

练习1:写一个playbook,判断某条件是否成立,成立了才执行task,否则不执行,命令如下

练习2:修改when-1.yaml的内容如下。

练习3:修改when-1.yaml的内容如下。

练习4:修改when-1.yaml的内容如下。

练习5:修改 when-1.yaml 的内容如下。 

 常见的判断符包括以下6种。

练习6:如果server2的系统主版本是7(RHEL/CentOS7),则打印111,否则不打印。playbook的内容如下

练习7:修改when-2.yaml 的内容如下。

1.2 When判断in的用法

练习:判断某值是否在列表中,编写 when-3.yaml,命令如下

1.3 When判断is的用法

2. 判断语句block-rescue

 练习1:按上面的描述写一个playbook,内容如下。

练习2: 修改block-1.yaml的内容如下。(添加ignore_erros: yes)

 3. 循环语句

练习1:定义一个列表users,然后循环这个列表中的每个元素,命令如下。 

练习2:修改loop-1.yaml的内容如下。

练习3:如果想打印所有性别为男的那些用户名,修改loop-1.yaml 的内容如下。


一个play中可以包含多个task,如果不想所有的task全部执行,可以设置只有满足某个
条件才执行这个task,不满足条件则不执行此task。本章主要讲解when 和 block-rescue两种判断语句。

 

1.判断语句When

when作为一个判断语句,出现在某个 task下,格式如下。
tasks:
  ‐ name: aa
  模块1
  when: 条件1
如果条件1成立,则执行模块1,否则不执行。
注意
在when中引用变量时是不用加{{}}的。
本章实验都在/home/duan/demo3下操作,先把 demo3目录创建出来并把ansible.cfg
和 hosts拷贝进去,命令如下。
[bdqn@RHEL813 ~]$ mkdir demo3
[bdqn@RHEL813 ~]$ cp ansible.cfg hosts demo3/
[bdqn@RHEL813 ~]$ cd demo3
[bdqn@RHEL813 demo3]$ ls
ansible.cfg  hosts
[bdqn@RHEL813 demo3]$ 

1.1 When判断中>、<、!=的使用

练习1:写一个playbook,判断某条件是否成立,成立了才执行task,否则不执行,命令如下
[bdqn@RHEL813 demo3]$ cat when-1.yaml 
---
- hosts: server2
  tasks:
          - name: tasks1
            debug: msg="111"
            when: 1<2
[bdqn@RHEL813 demo3]$ 
这里有一个task,判断1<2是否成立,如果成立则执行task1,屏幕上会显示111;如果不
成立则不执行taskl,屏幕上不会显示111。这里明显是成立的,所以会执行task1。运行结果如下
[bdqn@RHEL813 demo3]$ ansible-playbook when-1.yaml 

PLAY [server2] **********************************************************************************************************************

TASK [Gathering Facts] **************************************************************************************************************
ok: [server2]

TASK [tasks1] ***********************************************************************************************************************
ok: [server2] => {
    "msg": "111"
}

PLAY RECAP **************************************************************************************************************************
server2                    : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[bdqn@RHEL813 demo3]$ 
when后面可以有多个条件,用or或and作为连接符。
如果用or作为连接符,只要有一个条件成立即可,只有所有的条件都不成立时,整体才不成立。
练习2:修改when-1.yaml的内容如下。
[bdqn@RHEL813 demo3]$ cat when-1.yaml 
---
- hosts: server2
  tasks:
          - name: tasks1
            debug: msg="111"
            when: 1 < 2 or 2 > 3
[bdqn@RHEL813 demo3]$ 
此处用or作为连接符,只要有一个条件成立就会成立,2>3不成立,但是1<2成立,所以
整体上就是成立的。运行结果如下。
[bdqn@RHEL813 demo3]$ ansible-playbook when-1.yaml 

PLAY [server2] **********************************************************************************************************************

TASK [Gathering Facts] **************************************************************************************************************
ok: [server2]

TASK [tasks1] ***********************************************************************************************************************
ok: [server2] => {
    "msg": "111"
}

PLAY RECAP **************************************************************************************************************************
server2                    : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[bdqn@RHEL813 demo3]$ 
仍然会执行task1。
练习3:修改when-1.yaml的内容如下。
[bdqn@RHEL813 demo3]$ cat when-1.yaml 
---
- hosts: server2
  tasks:
          - name: tasks1
            debug: msg="111"
            when: 1 > 2 or 2 > 3
[bdqn@RHEL813 demo3]$ 
此处用or作为连接符,1>2不成立且2>3也不成立,所以整体上就是不成立的,不会执行
task1。运行结果如下。
[bdqn@RHEL813 demo3]$ ansible-playbook when-1.yaml 

PLAY [server2] **********************************************************************************************************************

TASK [Gathering Facts] **************************************************************************************************************
ok: [server2]

TASK [tasks1] ***********************************************************************************************************************
skipping: [server2]

PLAY RECAP **************************************************************************************************************************
server2                    : ok=1    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0   

[bdqn@RHEL813 demo3]$ 
也可以用and作为连接符,如果用and作为连接符,需要所有条件全部成立,只要有一个条件不成立,整体上就是不成立的。
练习4:修改when-1.yaml的内容如下。
[bdqn@RHEL813 demo3]$ cat when-1.yaml 
---
- hosts: server2
  tasks:
          - name: tasks1
            debug: msg="111"
            when: 2 > 1 and 2 > 3
[bdqn@RHEL813 demo3]$ 
这里虽然2>1是成立的,但是2>3不成立,所以整体上就是不成立的,因为用and作为连
接符,需要所有的条件都成立才可以,所以不会执行task1。运行结果如下。

 

[bdqn@RHEL813 demo3]$ ansible-playbook when-1.yaml 

PLAY [server2] **********************************************************************************************************************

TASK [Gathering Facts] **************************************************************************************************************
ok: [server2]

TASK [tasks1] ***********************************************************************************************************************
skipping: [server2]

PLAY RECAP **************************************************************************************************************************
server2                    : ok=1    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0   

[bdqn@RHEL813 demo3]$ 
在判断中,or 和 and是可以混用的,为了看得更清晰,可以使用小括号。
练习5:修改 when-1.yaml 的内容如下。 
[bdqn@RHEL813 demo3]$ cat when-1.yaml 
---
- hosts: server2
  tasks:
          - name: tasks1
            debug: msg="111"
            when: (1 > 2 or 2 != 1) and 2 > 3
[bdqn@RHEL813 demo3]$ 
这里(1>2 or 2!=1)作为一个整体,1>2不成立,但是2!=1(=是不等于的意思)成立,所以
此处( 1>2 or 2!=1)作为一个整体是成立的。and后面2>3不成立,所以整个when后面的判断是不成立的,不会执行此 task1。运行结果如下。

[bdqn@RHEL813 demo3]$ ansible-playbook when-1.yaml 

PLAY [server2] **********************************************************************************************************************

TASK [Gathering Facts] **************************************************************************************************************
ok: [server2]

TASK [tasks1] ***********************************************************************************************************************
skipping: [server2]

PLAY RECAP **************************************************************************************************************************
server2                    : ok=1    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0   

[bdqn@RHEL813 demo3]$ 
 常见的判断符包括以下6种。
(1)==:等于。
(2)!=:不等于。
(3)>:大于。
(4)>=:大于等于。
(5)<:小于。
(6)<=:小于等于。

练习6:如果server2的系统主版本是7(RHEL/CentOS7),则打印111,否则不打印。playbook的内容如下
[bdqn@RHEL813 demo3]$ cat when-2.yaml 
---
- hosts: server2
  tasks:
          - name: task2
            debug: msg="111"
            when: ansible_distribution_major_version == "7"
[bdqn@RHEL813 demo3]$ 
因为server2的系统是RHEL8,所以不会执行此task2,即不会显示111。
[bdqn@RHEL813 demo3]$ ansible-playbook when-2.yaml 

PLAY [server2] **********************************************************************************************************************

TASK [Gathering Facts] **************************************************************************************************************
ok: [server2]

TASK [task2] ************************************************************************************************************************
skipping: [server2]

PLAY RECAP **************************************************************************************************************************
server2                    : ok=1    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0   

[bdqn@RHEL813 demo3]$ 
注意
ansible_distribution major version的值是一个字符串,所以when判断中=后面的7是要加引号
练习7:修改when-2.yaml 的内容如下。
[bdqn@RHEL813 demo3]$ cat when-2.yaml 
---
- hosts: server2
  tasks:
          - name: task2
            debug: msg="111"
            when: ansible_distribution_major_version == "8"
[bdqn@RHEL813 demo3]$ 

再次运行此playbook,命令如下,会显示111。

[bdqn@RHEL813 demo3]$ ansible-playbook when-2.yaml 

PLAY [server2] **********************************************************************************************************************

TASK [Gathering Facts] **************************************************************************************************************
ok: [server2]

TASK [task2] ************************************************************************************************************************
ok: [server2] => {
    "msg": "111"
}

PLAY RECAP **************************************************************************************************************************
server2                    : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

 再次提醒:在when 中引用变量时是不用加{{}}

1.2 When判断in的用法

在when语句中,除可以使用上面的大于、小于等判断方法外,还可以使用 in,用法如
下。
value in 列表
如果此值在这个列表中,则判断成立,否则不成立。

 

练习:判断某值是否在列表中,编写 when-3.yaml,命令如下
[bdqn@RHEL813 demo3]$ cat when-3.yaml 
---
- hosts: server2
  vars:
          list1: [1,2,3,4]
  tasks:
          - name: tasks3
            debug: msg="333"
            when: 2 in list1

[bdqn@RHEL813 demo3]$ 
此处定义了一个列表 list1,里面有4个值,分别为1、2、3、4;定义了一个task打印333,会不会执行这个task,就要看when后面的判断是否成立。如果2在列表list1中,则执行;如果不在,则不执行,很明显2在列表list1中,所以会执行此task,即屏幕上会显示333。运行结果如下
[bdqn@RHEL813 demo3]$ ansible-playbook when-3.yaml 

PLAY [server2] **********************************************************************************************************************

TASK [Gathering Facts] **************************************************************************************************************
ok: [server2]

TASK [tasks3] ***********************************************************************************************************************
ok: [server2] => {
    "msg": "333"
}

PLAY RECAP **************************************************************************************************************************
server2                    : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[bdqn@RHEL813 demo3]$ 
因为2在列表list1中,when判断成立,可以正确执行task3,所以屏幕上会显示333。修
改when-3.yaml的内容如下。
[bdqn@RHEL813 demo3]$ cat when-3.yaml 
---
- hosts: server2
  vars:
          list1: [1,2,3,4]
  tasks:
          - name: tasks3
            debug: msg="333"
            when: 2 not in list1

[bdqn@RHEL813 demo3]$ 
这里判断的是2不在列表list1中,但2是在列表list1中的,所以判断不成立。运行结果如
下。
[bdqn@RHEL813 demo3]$ ansible-playbook when-3.yaml 

PLAY [server2] **********************************************************************************************************************

TASK [Gathering Facts] **************************************************************************************************************
ok: [server2]

TASK [tasks3] ***********************************************************************************************************************
skipping: [server2]

PLAY RECAP **************************************************************************************************************************
server2                    : ok=1    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0   

[bdqn@RHEL813 demo3]$ 
因为when判断不成立,所以屏幕上不会显示333。回想前面的例子。
[bdqn@RHEL813 ~]$ cat demo2/9-inventory1.yaml 
---
- hosts: db
  tasks:
          - name: 打印 我在清单中的名称
            debug: msg={{inventory_hostname}}
            when: inventory_hostname in groups ['xx']
[bdqn@RHEL813 ~]$ 
这里判断当前正在执行的主机是不是属于主机组xx,如果是则执行debug,如果不是则不执行

1.3 When判断is的用法

is可以用于判断变量是否被定义,常见的判断包括以下3种。
(1)is defined:变量被定义。
(2)is undefined:等同于is not defined,变量没有被定义。
(3)is none:变量被定义了,但是值为空。
看下面的例子。
[bdqn@RHEL813 demo3]$ cat when-4.yaml 
---
- hosts: server2
  vars:
          aa: 1
          bb: 
  tasks:
          - name: tasks1
            debug: msg="111"
            when: aa is undefined
          - name: tasks2
            debug: msg="222"
            when: bb is undefined
          - name: tasks3
            debug: msg="333"
            when: cc is not defined
[bdqn@RHEL813 demo3]$ 
首先定义了两个变量:aa和 bb,其中bb的值为空,此处并没有定义cc。后面定义了以下3个task
(1)如果aa被定义了,则显示111,这里aa被定义了,所以判断成立,会执行task1。
(2)如果b没有被定义,则显示222,这里bb被定义了,所以判断不成立,不会执行
task2。
(3)如果cc没有被定义,则显示333,这里cc没有被定义,所以判断成立,会执行
task3。
这里is undefined 和is not defined是一个意思。
查看运行的结果,如下所示。
[bdqn@RHEL813 demo3]$ ansible-playbook when-4.yaml 

PLAY [server2] **********************************************************************************************************************

TASK [Gathering Facts] **************************************************************************************************************
ok: [server2]

TASK [tasks1] ***********************************************************************************************************************
skipping: [server2]

TASK [tasks2] ***********************************************************************************************************************
skipping: [server2]

TASK [tasks3] ***********************************************************************************************************************
ok: [server2] => {
    "msg": "333"
}

PLAY RECAP **************************************************************************************************************************
server2                    : ok=2    changed=0    unreachable=0    failed=0    skipped=2    rescued=0    ignored=0   

[bdqn@RHEL813 demo3]$ 
练习:写一个playbook,内容如下
[bdqn@RHEL813 demo3]$ cat when-5.yaml 
---
- hosts: server2
  tasks:
          - name: 执行一个系统命令
            shell: "ls /aa.txt"
            register: aa
            ignore_errors: yes
          - name: tasks2
            fail: msg="命令执行错了001"
            when: aa.rc != 0
          - name: tasks3
            debug: msg="OK123"
[bdqn@RHEL813 demo3]$ 
运行此playbook命令如下
[bdqn@RHEL813 demo3]$ ansible-playbook when-5.yaml 

PLAY [server2] **********************************************************************************************************************

TASK [Gathering Facts] **************************************************************************************************************
ok: [server2]

TASK [执行一个系统命令] *********************************************************************************************************************
fatal: [server2]: FAILED! => {"changed": true, "cmd": "ls /aa.txt", "delta": "0:00:00.008831", "end": "2023-12-22 10:18:14.551873", "msg": "non-zero return code", "rc": 2, "start": "2023-12-22 10:18:14.543042", "stderr": "ls: 无法访问'/aa.txt': 没有那个文件或目录", "stderr_lines": ["ls: 无法访问'/aa.txt': 没有那个文件或目录"], "stdout": "", "stdout_lines": []}
...ignoring

TASK [tasks2] ***********************************************************************************************************************
fatal: [server2]: FAILED! => {"changed": false, "msg": "命令执行错了001"}

PLAY RECAP **************************************************************************************************************************
server2                    : ok=2    changed=1    unreachable=0    failed=1    skipped=0    rescued=0    ignored=1   

[bdqn@RHEL813 demo3]$ 

2. 判断语句block-rescue

对于when来说,只能做一个判断,成立就执行,不成立就不执行。block和rescue一般
同用,类似于shell判断语句中的if-else,在block下面可以包含多个模块,来判断这多个模块是否执行成功了。

block-rescue的用法如下。

block:
  ‐ 模块1
  ‐ 模块2
  ‐ 模块3
  rescue:
  ‐ 模块1
  ‐ 模块2
先执行 block中的模块1,如果没有报错,则继续执行模块2,如果block中的所有模块都
执行成功了,则跳过rescue 中的所有模块,直接执行下一个task中的模块,如图32-1所
  这里有2个task : task1和 task2,在 task1的block中有3个模块,rescue中有2个模块。
如果 block1中的所有模块都正确执行了,则不执行rescue中的模块,直接执行task2。
  如果 block中的任一模块执行失败,block中其他后续的模块都不再执行,然后会跳转执行rescue 中的模块,如图32-2所示。
Playbook控制语句_第1张图片
这里block1中的模块1执行完成之后会执行模块2,如果模块2报错,则不会执行模块3,
直接跳转到rescue中,执行模块x。rescue中的所有模块全部正确执行完成之后,则执行
task2

 如果rescue中的某个模块执行失败,则退出整个playbook,如图32-3所示。

这里 block中的模块2执行失败,则跳转到rescue中执行模块x,如果模块x执行失败,则退出整个 playbook,即也不会执行task2了。
如果某个报错模块有 ignore_errors: yes选项,则会忽略此模块的错误,继续执行下一个模块,如图32-4所示。
这里block中的模块2执行失败了,但是因为加了ignore_errors: yes选项,所以会忽略这
个报错模块,继续执行模块3。

 练习1:按上面的描述写一个playbook,内容如下。

[bdqn@RHEL813 demo3]$ cat block-1.yaml 
---
- hosts: server2
  tasks:
          - name: tasks1
            block:
                    - name: 11
                      debug: msg="1111"

                    - name: 22
                      shell: "ls /aa.txt"

                    - name: 33
                      debug: msg="3333"

            rescue:
                    - name: xx
                      debug: msg="xxxx"

                    - name: yy
                      debug: msg="yyyy"
                              
                    - name: tasks2
                      debug: msg="zzzz"
[bdqn@RHEL813 demo3]$ 
这里在task1的block中运行了3个模块,第一个模块可以正确执行,第二个模块是执行一
个系统命令ls /aa.txt,但是在server2中是不存在/aa.txt这个文件的,所以这个模块会执行失败。block中的第三个模块不再执行,直接跳转到rescue中的模块。rescue中的2个模块均可正确执行,然后执行task2。
所以,屏幕上会显示1111, xxxx, yyyy, zzzz。运行结果如下。
[bdqn@RHEL813 demo3]$ ansible-playbook block-1.yaml 

PLAY [server2] **********************************************************************************************************************

TASK [Gathering Facts] **************************************************************************************************************
ok: [server2]

TASK [debug] ************************************************************************************************************************
ok: [server2] => {
    "msg": "1111"
}

TASK [shell] ************************************************************************************************************************
fatal: [server2]: FAILED! => {"changed": true, "cmd": "ls /aa.txt", "delta": "0:00:00.005576", "end": "2023-12-22 10:46:34.520144", "msg": "non-zero return code", "rc": 2, "start": "2023-12-22 10:46:34.514568", "stderr": "ls: 无法访问'/aa.txt': 没有那个文件或目录", "stderr_lines": ["ls: 无法访问'/aa.txt': 没有那个文件或目录"], "stdout": "", "stdout_lines": []}

TASK [xx] ***************************************************************************************************************************
ok: [server2] => {
    "msg": "xxxx"
}

TASK [yy] ***************************************************************************************************************************
ok: [server2] => {
    "msg": "yyyy"
}

TASK [tasks2] ***********************************************************************************************************************
ok: [server2] => {
    "msg": "zzzz"
}

PLAY RECAP **************************************************************************************************************************
server2                    : ok=5    changed=0    unreachable=0    failed=0    skipped=0    rescued=1    ignored=0   

[bdqn@RHEL813 demo3]$ 

练习2: 修改block-1.yaml的内容如下。(添加ignore_erros: yes)

[bdqn@RHEL813 demo3]$ cat block-1.yaml 
---
- hosts: server2
  tasks:
          - name: tasks1
            block:
                    - name: 11
                      debug: msg="1111"

                    - name: 22
                      shell: "ls /aa.txt"
                      ignore_errors: yes

                    - name: 33
                      debug: msg="3333"

            rescue:
                    - name: xx
                      debug: msg="xxxx"

                    - name: yy
                      debug: msg="yyyy"
                              
                    - name: tasks2
                      debug: msg="zzzz"
[bdqn@RHEL813 demo3]$ 
与上面的例子相比,在 block的第二个模块中增加了一个 ignore_errors: yes选项,这样
block中的第二个模块即使报错了,也会忽略这个报错继续执行第三个模块。然后执行task2, 所以屏幕上会显示1111,3333。运行结果如下
[bdqn@RHEL813 demo3]$ ansible-playbook block-1.yaml 

PLAY [server2] **********************************************************************************************************************

TASK [Gathering Facts] **************************************************************************************************************
ok: [server2]

TASK [debug] ************************************************************************************************************************
ok: [server2] => {
    "msg": "1111"
}

TASK [shell] ************************************************************************************************************************
fatal: [server2]: FAILED! => {"changed": true, "cmd": "ls /aa.txt", "delta": "0:00:00.005930", "end": "2023-12-22 10:50:16.769375", "msg": "non-zero return code", "rc": 2, "start": "2023-12-22 10:50:16.763445", "stderr": "ls: 无法访问'/aa.txt': 没有那个文件或目录", "stderr_lines": ["ls: 无法访问'/aa.txt': 没有那个文件或目录"], "stdout": "", "stdout_lines": []}
...ignoring

TASK [debug] ************************************************************************************************************************
ok: [server2] => {
    "msg": "3333"
}

PLAY RECAP **************************************************************************************************************************
server2                    : ok=4    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=1   

[bdqn@RHEL813 demo3]$ 

 3. 循环语句

在shell中 for循环的用法如下。
for i in A B C ... ; do
 命令 $
 done
这里首先把A赋值给i,执行do和done之间的命令;然后把B赋值给i,执行do和 done之间
的命令,以此类推,直到把in后面所有的值执行完毕。for后面的变量可以随便命名。

再回顾一下前面介绍的列表,如下所示。  

employee:
 ‐ uname: lisi
 age: 22
 sex: man

 ‐ uname: wangwu
 age: 24
 sex: man

 ‐ uname: xiaohua
 age: 21
这里列表employee中有3个元素,分别记录了lisi、wangwu、xiaohua的信息。我们把
这3个元素当成刚讲的for循环中的A、B、C。先把第一个元素赋值给变量,执行某个操作,完成之后再把第二个元素赋值给变量。
用for循环A、B、C,在playbook中用loop来循环列表中的元素。在for循环中,指定一个
变量如i,然后分别把A、B、C赋值给i。
在loop中,使用一个固定的变量 item,然后把每个元素赋值给item,如图32-5所示。第
二次循环,如图32-6所示。
Playbook控制语句_第2张图片

练习1:定义一个列表users,然后循环这个列表中的每个元素,命令如下。 

[bdqn@RHEL813 demo3]$ cat loop-1.yaml 
---
- hosts: server2
  vars:
          users:
                  - uname: tom
                    age: 20
                    sex: man
                  
                  - uname: bob
                    age: 22
                    sex: man

                  - uname: mary
                    age: 20
                    sex: woman
  tasks:
          - name: tasks1
            debug: msg={{ item }}
            loop: "{{ users }}"
[bdqn@RHEL813 demo3]$ 
这里定义了一个列表users,里面包含了3个用户的信息,在taskl中用loop开始循环这个
列表。loop后面写列表名时,需要使用引号引起来,这里的关键字loop可以换成关键字
with_items。
这里首先把users的第一个元素赋值给item,用debug 打印;然后把users的第二个元素赋
值给item,用 debug打印,直到把所有的元素都赋值给 item。
运行此 playbook,命令如下。
[bdqn@RHEL813 demo3]$ ansible-playbook loop-1.yaml 

PLAY [server2] **********************************************************************************************************************

TASK [Gathering Facts] **************************************************************************************************************
ok: [server2]

TASK [tasks1] ***********************************************************************************************************************
ok: [server2] => (item={'uname': 'tom', 'age': 20, 'sex': 'man'}) => {
    "msg": {
        "age": 20,
        "sex": "man",
        "uname": "tom"
    }
}
ok: [server2] => (item={'uname': 'bob', 'age': 22, 'sex': 'man'}) => {
    "msg": {
        "age": 22,
        "sex": "man",
        "uname": "bob"
    }
}
ok: [server2] => (item={'uname': 'mary', 'age': 20, 'sex': 'woman'}) => {
    "msg": {
        "age": 20,
        "sex": "woman",
        "uname": "mary"
    }
}

PLAY RECAP **************************************************************************************************************************
server2                    : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[bdqn@RHEL813 demo3]$ 
如果不想打印每个元素的所有条目,只想打印每个元素的uname呢?答案:可以通过练习2解决。

练习2:修改loop-1.yaml的内容如下。

[bdqn@RHEL813 demo3]$ cat loop-1.yaml 
---
- hosts: server2
  vars:
          users:
                  - uname: tom
                    age: 20
                    sex: man
                  
                  - uname: bob
                    age: 22
                    sex: man

                  - uname: mary
                    age: 20
                    sex: woman
  tasks:
          - name: tasks1
            debug: msg={{ item.uname }}
            loop: "{{ users }}"
[bdqn@RHEL813 demo3]$ 
列表的每个元素都是一个字典,所以 item就是字典,要获取这个字典中的uname变量,用 item.uname即可。
运行此 playbook,命令如下。
[bdqn@RHEL813 demo3]$ ansible-playbook loop-1.yaml 

PLAY [server2] **********************************************************************************************************************

TASK [Gathering Facts] **************************************************************************************************************
ok: [server2]

TASK [tasks1] ***********************************************************************************************************************
ok: [server2] => (item={'uname': 'tom', 'age': 20, 'sex': 'man'}) => {
    "msg": "tom"
}
ok: [server2] => (item={'uname': 'bob', 'age': 22, 'sex': 'man'}) => {
    "msg": "bob"
}
ok: [server2] => (item={'uname': 'mary', 'age': 20, 'sex': 'woman'}) => {
    "msg": "mary"
}

PLAY RECAP **************************************************************************************************************************
server2                    : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[bdqn@RHEL813 demo3]$ 

练习3:如果想打印所有性别为男的那些用户名,修改loop-1.yaml 的内容如下。

[bdqn@RHEL813 demo3]$ cat loop-1.yaml 
---
- hosts: server2
  vars:
          users:
                  - uname: tom
                    age: 20
                    sex: man
                  
                  - uname: bob
                    age: 22
                    sex: man

                  - uname: mary
                    age: 20
                    sex: woman
  tasks:
          - name: tasks1
            debug: msg={{ item.uname }}
            when: item.sex == "man"
            loop: "{{ users }}"
[bdqn@RHEL813 demo3]$ 
在此playbook中,我们用when加了一个判断。循环列表时,首先把第一个元素赋值给
item,然后判断item.sex的值是否为man,如果是则判断成立,执行debug模块;如果不是则判断不成立,不执行debug模块。
第一次循环结束之后,开始第二次循环,把第二个元素赋值给item之后,做相同的判
断。运行此 playbook,命令如下。
[bdqn@RHEL813 demo3]$ ansible-playbook loop-1.yaml 

PLAY [server2] **********************************************************************************************************************

TASK [Gathering Facts] **************************************************************************************************************
ok: [server2]

TASK [tasks1] ***********************************************************************************************************************
ok: [server2] => (item={'uname': 'tom', 'age': 20, 'sex': 'man'}) => {
    "msg": "tom"
}
ok: [server2] => (item={'uname': 'bob', 'age': 22, 'sex': 'man'}) => {
    "msg": "bob"
}
skipping: [server2] => (item={'uname': 'mary', 'age': 20, 'sex': 'woman'}) 

PLAY RECAP **************************************************************************************************************************
server2                    : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[bdqn@RHEL813 demo3]$ 
这样就把所有性别为男的用户名打印出来了。

你可能感兴趣的:(linux,运维,服务器)