RHCE8 资料整理
- 第 32 章 控制语句
- 32.1 判断语句 when
- 32.1.1 when 判断中>、<、!=和==的使用
- 32.1.2 when 判断中 in的用法
- 32.1.3 when 判断中 is的用法
- 32.2 判断语句 block-rescue
- 32.3 循环语句
第 32 章 控制语句
一个play中可以包含多个task,如果不想所有的task全部执行,可以设置只有满足某个条件才执行这个task。本章主要介绍when
和block-rescue
两种判断语句。
32.1 判断语句 when
when作为一个判断语句,出现在某个task下,格式,
tasks:
- name: xxx模块when: 条件
如果条件成立,则执行模块,否则不执行。
在when中引用变量时是不用加{{}}的
32.1.1 when 判断中>、<、!=和==的使用
when后面可以有多个判断条件,使用or
或and
作为连接符
常见的判断符包括:
符号 | 说明 |
---|---|
== | 等于 |
!= | 不等于 |
> | 大于 |
=> | 大于等于 |
< | 小于 |
<= | 小于等于 |
[root@node-137 ansible]# cat when-1.yml
---
- hosts: db1tasks:- name: when testdebug: msg="1<2"when: 1<2- name: when test2debug: msg="1>2"when: 1>2- debug: msg="1>2 or 2<3"when: 1>2 or 2<3- debug: msg="2>1 and 3>2"when: 2>1 and 3>2- debug: msg="centos:7"when: ansible_distribution_major_version=="7"
[root@node-137 ansible]# ansible-playbook when-1.ymlPLAY [db1] ****************************************************************************************************************************TASK [Gathering Facts] ****************************************************************************************************************
ok: [node-138]TASK [when test] **********************************************************************************************************************
ok: [node-138] => {"msg": "1<2"
}TASK [when test2] *********************************************************************************************************************
skipping: [node-138]TASK [debug] **************************************************************************************************************************
ok: [node-138] => {"msg": "1>2 or 2<3"
}TASK [debug] **************************************************************************************************************************
ok: [node-138] => {"msg": "2>1 and 3>2"
}TASK [debug] **************************************************************************************************************************
ok: [node-138] => {"msg": "centos:7"
}PLAY RECAP ****************************************************************************************************************************
node-138 : ok=5 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
当判断条件不成立,则会提示
skipping
32.1.2 when 判断中 in的用法
在when语句中,除可以使用上面的大于、小于等判断方法外,还可以使用in
,如下
value [not] in 列表
如果此值在这个列表中,则判断成立,否则不成立
[root@node-137 ansible]# cat when-3.yml
---
- hosts: db1gather_facts: falsevars:list1: [1,2,3,4,5]tasks:- debug: msg="123"when: 1 in list1- debug: msg="not in"when: 6 not in list1
[root@node-137 ansible]# ansible-playbook when-3.ymlPLAY [db1] ****************************************************************************************************************************TASK [debug] **************************************************************************************************************************
ok: [node-138] => {"msg": "123"
}TASK [debug] **************************************************************************************************************************
ok: [node-138] => {"msg": "not in"
}PLAY RECAP ****************************************************************************************************************************
node-138 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
32.1.3 when 判断中 is的用法
is
可以用于判断变量是否被定义,常见的判断包括以下3种:
is defined
,变量被定义is undefined
,变量未被定义,等同于is not defined
is noe
,变量被定义了,但值为空
[root@node-137 ansible]# cat when-4.yml
---
- hosts: db1gather_facts: truevars:aa: 123dd:tasks:- debug: msg={{aa}}when: aa is defined- debug: msg="bb"when: bb is not defined- debug: msg="cc"when: cc is undefined- debug: msg="dd"when: dd is none
[root@node-137 ansible]# ansible-playbook when-4.ymlPLAY [db1] ****************************************************************************************************************************TASK [Gathering Facts] ****************************************************************************************************************
ok: [node-138]TASK [debug] **************************************************************************************************************************
ok: [node-138] => {"msg": 123
}TASK [debug] **************************************************************************************************************************
ok: [node-138] => {"msg": "bb"
}TASK [debug] **************************************************************************************************************************
ok: [node-138] => {"msg": "cc"
}TASK [debug] **************************************************************************************************************************
ok: [node-138] => {"msg": "dd"
}PLAY RECAP ****************************************************************************************************************************
node-138 : ok=5 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
判断文件的小练习
[root@node-137 ansible]# cat when-5.yml
---
- hosts: db1tasks:- name: run syscmdshell: "ls /aa.txt"register: aaignore_errors: true- name: task2fail: msg="命令执行错误"when: aa.rc != 0- name: task3debug: msg="OK123"
[root@node-137 ansible]# ansible-playbook when-5.ymlPLAY [db1] ****************************************************************************************************************************TASK [Gathering Facts] ****************************************************************************************************************
ok: [node-138]TASK [run syscmd] *********************************************************************************************************************
fatal: [node-138]: FAILED! => {"changed": true, "cmd": "ls /aa.txt", "delta": "0:00:00.037543", "end": "2023-12-20 21:02:05.426760", "msg": "non-zero return code", "rc": 2, "start": "2023-12-20 21:02:05.389217", "stderr": "ls: cannot access /aa.txt: No such file or directory", "stderr_lines": ["ls: cannot access /aa.txt: No such file or directory"], "stdout": "", "stdout_lines": []}
...ignoringTASK [task2] **************************************************************************************************************************
fatal: [node-138]: FAILED! => {"changed": false, "msg": "命令执行错误"}PLAY RECAP ****************************************************************************************************************************
node-138 : ok=2 changed=1 unreachable=0 failed=1 skipped=0 rescued=0 ignored=1
32.2 判断语句 block-rescue
对于when来说,只能做一个判断,成立就执行,不成立就不执行。block
和rescue
一般同用,类似于shell判断语句中的if-else,在block下面可以包含多个模块,来判断这多个模块是否执行成功。用法,
block:
- 模块1
- 模块2
- 模块3
rescue:
- 模块4
- 模块5
执行流程:
- 首先执行
task1
的block
中的模块1
,如果成功,则继续执行block
中的模块2
,如果block
中所有模块均执行成功,则跳过rescue
中的模块,进而执行task2
中的模块 - 当执行
task1
的block
中的某个模块
失败,则执行rescue
中的模块4
,如果rescue
中的所有模块均执行成功,则继续执行task2
中的模块,如果rescue
中的某个模块失败,则退出playbook - 如果
block
或rescue
的模块中,有ignore_errors: yes
选项,则会忽略该报错模块
示例1,参考图1
[root@node-137 ansible]# cat block-1.yml
---
- hosts: db1tasks:- name: task1block:- debug: msg="block1"- shell: "ls /"- debug: msg="block2"rescue:- debug: msg="rescue1"- debug: msg="rescue2"- name: task2debug: msg="task2"[root@node-137 ansible]# ansible-playbook block-1.ymlPLAY [db1] ****************************************************************************************************************************TASK [Gathering Facts] ****************************************************************************************************************
ok: [node-138]TASK [debug] **************************************************************************************************************************
ok: [node-138] => {"msg": "block1"
}TASK [shell] **************************************************************************************************************************
changed: [node-138]TASK [debug] **************************************************************************************************************************
ok: [node-138] => {"msg": "block2"
}TASK [task2] **************************************************************************************************************************
ok: [node-138] => {"msg": "task2"
}PLAY RECAP ****************************************************************************************************************************
node-138 : ok=5 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
示例2,参考图2
[root@node-137 ansible]# cat block-1.yml
---
- hosts: db1tasks:- name: task1block:- debug: msg="block1"- shell: "ls /aa.txt"- debug: msg="block2"rescue:- debug: msg="rescue1"- debug: msg="rescue2"- name: task2debug: msg="task2"
[root@node-137 ansible]# ansible-playbook block-1.ymlPLAY [db1] ****************************************************************************************************************************TASK [Gathering Facts] ****************************************************************************************************************
ok: [node-138]TASK [debug] **************************************************************************************************************************
ok: [node-138] => {"msg": "block1"
}TASK [shell] **************************************************************************************************************************
fatal: [node-138]: FAILED! => {"changed": true, "cmd": "ls /aa.txt", "delta": "0:00:00.032879", "end": "2023-12-20 21:52:57.557622", "msg": "non-zero return code", "rc": 2, "start": "2023-12-20 21:52:57.524743", "stderr": "ls: cannot access /aa.txt: No such file or directory", "stderr_lines": ["ls: cannot access /aa.txt: No such file or directory"], "stdout": "", "stdout_lines": []}TASK [debug] **************************************************************************************************************************
ok: [node-138] => {"msg": "rescue1"
}TASK [debug] **************************************************************************************************************************
ok: [node-138] => {"msg": "rescue2"
}TASK [task2] **************************************************************************************************************************
ok: [node-138] => {"msg": "task2"
}PLAY RECAP ****************************************************************************************************************************
node-138 : ok=5 changed=0 unreachable=0 failed=0 skipped=0 rescued=1 ignored=0
示例3,参考图3
[root@node-137 ansible]# cat block-1.yml
---
- hosts: db1tasks:- name: task1block:- debug: msg="block1"- shell: "ls /aa.txt"ignore_errors: true- debug: msg="block2"rescue:- debug: msg="rescue1"- debug: msg="rescue2"- name: task2debug: msg="task2"
[root@node-137 ansible]# ansible-playbook block-1.ymlPLAY [db1] ****************************************************************************************************************************TASK [Gathering Facts] ****************************************************************************************************************
ok: [node-138]TASK [debug] **************************************************************************************************************************
ok: [node-138] => {"msg": "block1"
}TASK [shell] **************************************************************************************************************************
fatal: [node-138]: FAILED! => {"changed": true, "cmd": "ls /aa.txt", "delta": "0:00:00.035454", "end": "2023-12-20 21:56:08.510199", "msg": "non-zero return code", "rc": 2, "start": "2023-12-20 21:56:08.474745", "stderr": "ls: cannot access /aa.txt: No such file or directory", "stderr_lines": ["ls: cannot access /aa.txt: No such file or directory"], "stdout": "", "stdout_lines": []}
...ignoringTASK [debug] **************************************************************************************************************************
ok: [node-138] => {"msg": "block2"
}TASK [task2] **************************************************************************************************************************
ok: [node-138] => {"msg": "task2"
}PLAY RECAP ****************************************************************************************************************************
node-138 : ok=5 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=1
32.3 循环语句
在playbook中用loop
来循环列表中的元素,在loop
中,使用一个固定的变量item
,然后把每个元素赋值给item
。格式,
list1: [a,b,c]
...
debug: msg={{item}}
loop: "{{list1}}"
#或
#with_items: "{{list1}}"
- 这里关键字
loop
可以替换为with_items
,含义相同 loop
或with_items
后面的{{}}
需要使用""
双引号或''
单引号引起来
[root@node-137 ansible]# cat loop-1.yml
---
- hosts: db1gather_facts: falsevars:users:- uname: "tom"age: 18- uname: "jerry"age: 19- uname: "jacky"age: 18tasks:- debug: msg={{ item }}with_items: "{{users}}"- debug: msg={{item.uname}}loop: '{{users}}'- debug: msg={{item}}when: item.age == 18loop: "{{users}}"
[root@node-137 ansible]# ansible-playbook loop-1.ymlPLAY [db1] ****************************************************************************************************************************TASK [debug] **************************************************************************************************************************
ok: [node-138] => (item={u'uname': u'tom', u'age': 18}) => {"msg": {"age": 18,"uname": "tom"}
}
ok: [node-138] => (item={u'uname': u'jerry', u'age': 19}) => {"msg": {"age": 19,"uname": "jerry"}
}
ok: [node-138] => (item={u'uname': u'jacky', u'age': 18}) => {"msg": {"age": 18,"uname": "jacky"}
}TASK [debug] **************************************************************************************************************************
ok: [node-138] => (item={u'uname': u'tom', u'age': 18}) => {"msg": "tom"
}
ok: [node-138] => (item={u'uname': u'jerry', u'age': 19}) => {"msg": "jerry"
}
ok: [node-138] => (item={u'uname': u'jacky', u'age': 18}) => {"msg": "jacky"
}TASK [debug] **************************************************************************************************************************
ok: [node-138] => (item={u'uname': u'tom', u'age': 18}) => {"msg": {"age": 18,"uname": "tom"}
}
skipping: [node-138] => (item={u'uname': u'jerry', u'age': 19})
ok: [node-138] => (item={u'uname': u'jacky', u'age': 18}) => {"msg": {"age": 18,"uname": "jacky"}
}PLAY RECAP ****************************************************************************************************************************
node-138 : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
在最后一个task中,加入判断语句when,使age等于18的user进行打印
with_items
还能够迭代字典,而loop
不行
[root@node-137 ansible]# cat loop-1.yml
---
- hosts: db1gather_facts: falsevars:userdict:users:uname: "tom"age: 18age1: 18users2:uname: "jea"age: 19age1: 20tasks:- debug: msg={{ item }}ignore_errors: truewith_items: "{{userdict.users}}"- debug: msg={{ item }}loop: "{{userdict}}"
[root@node-137 ansible]# ansible-playbook loop-1.ymlPLAY [db1] ****************************************************************************************************************************TASK [debug] **************************************************************************************************************************
ok: [node-138] => (item=uname) => {"msg": "uname"
}
ok: [node-138] => (item=age) => {"msg": "age"
}
ok: [node-138] => (item=age1) => {"msg": "age1"
}TASK [debug] **************************************************************************************************************************
fatal: [node-138]: FAILED! => {"msg": "Invalid data passed to 'loop', it requires a list, got this instead: {u'users2': {u'uname': u'jea', u'age': 19, u'age1': 20}, u'users': {u'uname': u'tom', u'age': 18, u'age1': 18}}. Hint: If you passed a list/dict of just one element, try adding wantlist=True to your lookup invocation or use q/query instead of lookup."}PLAY RECAP ****************************************************************************************************************************
node-138 : ok=1 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0