RHCE(ansible语句)

一:when语句

1:基础了解

 说到底,还是有多个表达式来组成一个判断语句,很多种的判断语句

1、 为什么需要判断语句:

有的时候play的结果需要依赖于变量,fact或者是前一个任务的执行结果,或者基于上一个task执行返回的结果而决定如何执行后续的task,这个时候就需要条件的判断了,一个很简单的案例,就是挂载磁盘,不需要到被控节点上面去看是否挂成功了,直接使用一个判断,看那个task任务的执行的结果,为0则代表着成功,就进行下一步的任务的执行

 2、使用场景

  1)目标主机上定义了一个硬限制,比如目标主机的最小内存必须达到多少,才能执行task任务

  2)捕获一个命令的输出,根据输出的结果不同来触发不同的task

  3)根据不同的目标主机的facts,来执行不同的tasks,如果是node1就是执行A任务,如果是node2就执行B任务

  等等等

3、when理解

当判断的结果是一致的话,那么执行task任务,否则的话,就跳过这个任务 

ansible中判断语句是when判断,默认when判断,就识别变量,所以的话,不需要使用"{{}}"来引用变量,when  inventory_hostname == 'node1'

还有一个点就是如果不使用变量的话,就只使用这个值的话,那么的话就要带上这个双引号,并且里面还要有单引号即可

when与模块的层级是一样的

 

2:判断的表达式

1:比较运算符

==  比较2边是否相等的,比较字符串和数字

!=  2边是否一致,不一致则为真

>=  比较大小,左边大于右边为真

<=  右边大于左边为真

>  左边大于右边为真

<  右边大于左边为真

案例:

判断运行的task任务的主机是不是node1,如果是的node1则执行任务,

判断主机的freemem大小是否大于1000,如果是的话,则执行任务

//通过facts变量来获取这个内存,然后通过魔法变量来获取这个node1
- name: memfree
  hosts: node1
  tasks:
    - name: use when
      debug:
        msg: dayu1000
      when: ansible_memtotal_mb > 1000
    - name: node1
      debug:
        msg: hostname is node1
      when: inventory_hostname == 'node1'

2:逻辑运算符

 

and 逻辑与,2边都为真,则返回真
or 逻辑或,有一个为真,则返回为真
not 逻辑否,对表达式取反,真为假,假为真,在表达式的前面写上
() 当一组的表达式组合在一起后,形成一个更大的表达式,组合内的所有表达式都是逻辑与的关系

案例:

#判断主机名为node1,ip地址为10,则打印hello rhce
[root@controller mnt]# cat f4.yml 
- name: use debug
  hosts: node1
  tasks:
    - debug:
        msg: hello rhce
      when: inventory_hostname == 'node1' and ansible_ens160.ipv4.address == '172.25.250.11'

#判断主机名是否为node1或者ip地址是30的,则打印rhce
[root@controller mnt]# cat f5.yaml 
- name:
  hosts: all
  tasks:
    - debug:
       msg: rhce
      when: inventory_hostname == 'node1' or ansible_ens160.ipv4.address == '172.25.250.30'

#使用not来进行判断,判断不是node1的主机即执行任务
应该放在最前面
- name: user kkk
  hosts: all
  tasks:
    - name:
      debug:
        msg: hello
      when: not ansible_hostname == 'node1'


#()的使用,主机名是node1并且ip地址是11或者系统是redhat,并且版本是9的则执行任务
()里面是逻辑与的关系,多个表达式一起表达
[root@controller mnt]# cat f7.yml 
- name: use debug
  hosts: all
  tasks:
    - debug:
        msg: hello rhce
      when: (ansible_hostname == 'node1' and ansible_ens160.ipv4.address == '172.25.250.11') or (ansible_distribution_major_version == '9' and ansible_os_family == 'RedHat')

3:根据rc的返回值来进行判断task任务是否执行成功

根据注册变量,这个能保存上一个tasks任务的执行信息,就是根据rc的值为0则表示执行成功,执行任务,不成功,执行另外的一个任务

[root@controller mnt]# cat f8.yml 
- hosts: node1
  tasks:
    - shell: ls /etc/passsssss
      register: get_status
      ignore_errors: yes
    - debug:
       msg: rc is 0
      when: get_status.rc == 0
    - debug:
       msg: rc is error
      when: get_status.rc != 0

4:通过条件判断路径是否存在

shell脚本也有这个使用test -f 路径,判断是否是一个文件,-d判断是否是一个目录,-e 路径,判断路径是否存在

ansible中,判断的格式如下

file:判断指定路径是否为一个文件,是则为真

directory:判断指定路径是否是一个目录,是则为真

link:判断指定路径是否为一个软连接,是则为真

mount:判断路径是否为挂载点,是则为真

exists:判断指定路径是否存在,存在则为真

使用when来进行判断 when "'/etc/passwd' is exists "

使用的关键字就是is

使用变量的值进行判断

#/etc/passwd存在的话,就执行任务
#when直接使用值的话需要使用双引号里面的值在加上单引号即可
[root@controller mnt]# cat f9.yaml 
- hosts: all
  tasks:
    - debug:
       msg: exist
      when: "'/etc/passwd is exists'"

5:通过判断tasks任务的执行结果(是对整个task任务进行判断)

ok:目标状态和期望值一致,没有发生变更

change或changed:目标发生变更,与期望值一样

sucess或succeeded:目标状态与期望值一样,或者任务执行成功了

failure或failed:任务失败

skip或skipped:任务跳过,注意,如果一个错误的任务使用ignore_errors忽略了这个错误,会跳过,但是实际上这个任务的执行是失败的,并没有跳过注意) 

案例:

#使用一个错误的任务,错误的结果就执行任务
- hosts: all
  tasks:
    - shell: ls /etc/passssss
      register: get_status
      ignore_errors: yes
    - debug:
       msg: is filed
      when: get_status is failed
    - debug:
       msg: is skipped
      when: get_status is skip  

6:通过对变量进行判断

defined:判断变量是否已定义了,定义了则返回真

undefined:判断变量是否未定义,未定义则返回真

none:判断变量的值是否为空,如果变量的已定义但是值为空的话,则返回真,定义了这个变量名,但是没有值

案例:

#定义一个变量,然后不给他的值,则执行任务
- hosts: node1
  vars:
    rhel:
  tasks:
    - debug:
       msg: is none
      when: rhel is none
    - debug:
       msg: is undefined
      when: rhel is undefined  

7:通过字符串进行判断大小写字母

lower:判断字符串是否是小写字母

upper:判断字符串是否是大写字母

[root@controller mnt]# cat f12.yml 
- hosts: node1
  vars:
    rhel: qqqq
  tasks:
    - debug:
       msg: lower
      when: rhel is lower  

8:通过数字来进行判断

even:判断数值是否为偶数,是则为真

odd:判断数值是否为奇数,,是则为真

divisibleby(num):判断是否可以整除指定的数值,是则为真

#判断能被2整除吗。是的话就执行任务
[root@controller mnt]# cat f12.yml 
- hosts: node1
  vars:
    rhel: 10
  tasks:
    - debug:
       msg: oushu
      when: rhel is divisibleby(2)

9:通过判断是否是子集或者是父集,in的判断

数字和字符都行

subset():判断一个list是不是另外一个list的子集,when:  a is subnet(b)

就是判断a是不是b的子集,就是a是不是被包含在b里面,小的

superset():判断一个list是不是另外一个list的父集;when: b is superset(a)

判断a是不是b的父集,就是a是不是包含b,大的

写法的话就是使用列表的形式来编写,不能使用字典的形式,会出现错误

案例:

[root@controller mnt]# cat f13.yml 
- hosts: node1
  vars:
    f:
      - qqq
      - www
    w:
      - qqq
  tasks:
    - debug:
       msg: fuji
      when: f is superset(w)   

 判断字符串是否位于一个列表中的(非常重要的,经常使用的)

判断ens160网卡是不是在ansible_intreafces里面

[root@controller mnt]# cat f3.yml 
- hosts: node1
  tasks:
    - debug:
       msg: ens160 exists
      when: "'ens160' in ansible_interfaces"

10:判断对象是否是字符串或者数字

string:判断是否是字符串

numbber:判断是否是数字

[root@controller mnt]# cat f14.yml 
- hosts: node1
  vars:
    rhel: 9
  tasks:
    - debug:
       msg: 9 is number
      when: rhel is number

3:when判断和其他的关键字

1、block关键字

使用when判断的时候,每一个when判断只会判断一个task任务,如果有多个的话,就需要编写多次的,这样的话,代码就非常的多且不必要了

解决的方法就是: 

ansible通过block包裹多个tasks的任务,直接对block进行when判断,如果判断成功,则执行block中的所有tasks任务

通俗来讲就是block是一个块,把多个tasks任务作为一个整体,对block进行判断,如果成立则block中的tasks任务执行

案例:
创建一个文件,创建一个目录,然后对其进行判断,直接对这个block进行判断,判断主机名是node1执行

#上面所述就有2个tasks任务,如果使用when的话,要使用2次,使用block的话,直接对这个block这个整体进行判断,即能执行
block的层级是包裹这些任务的,然后when对这个block进行判断,成功,则执行这个任务
- name: use block
  hosts: all
  tasks:
    - block:
      - file: 
          path: /mnt/1.txt
          state: touch
      - file:
          path: /mnt/1.dir
          state: directory
      when: inventory_hostname == 'node1'

2、resuce关键字

层级与block一样的,错误拯救,对于block块的话,如果block中的任务执行失败,则会执行resuce下面的任务,如果没有失败的话,则不会触发resuce关键字下的task任务

- name: rescue
  hosts: all
  tasks:
    - block:
       - shell: ls /etc/p11111
       - file:
          path: /etc/passwd
          state: file
      rescue:
        - debug:
           msg: rescue
      when: inventory_hostname == 'node1'

3、always关键字

无论block任务执行成功还是失败,都要执行always关键字的中task任务

- name: rescue
  hosts: all
  tasks:
    - block:
       - shell: ls /etc/p11111
       - file:
          path: /etc/passwd
          state: file
      rescue:
        - debug:
           msg: rescue
      always:
         - debug:
            msg: always
      when: inventory_hostname == 'node1'

4、fail和failed_when  

如果一个task任务执行失败的话,后面的task任务也没有必要执行,需要执行退出

就是挂载都没有挂上去,就不需要写yum仓库等等

案例:

- name: faile
  hosts: node1
  tasks:
    - shell: ls /etc/lllll
      ignore_errors: yes
      register: get_status
    - fail:
          msg: juben exit
      when: get_status.rc != 0
    - debug:
       msg: a

思路:
忽略了错误,继续像下面执行任务,本来要打印这个a的,使用了fail关键字,符合条件就退出这个剧本

failed_when:关键字

案例:

- name: faile
  hosts: node1
  tasks:
    - shell: ls /etc/lllll
      ignore_errors: yes
      register: get_status
    - debug:
        msg: juben exit
      failed_when: get_status.rc != 0
    - debug:
       msg: a

二:ansible循环语句

循环语句进行批量化的操作,创建用户,创建文件等

1:基于列表的循环(with_items)

不能使用对象(字典)的方式进行循环,会报错的,item固定的格式

2种写法
第一种,利用变量的形式
- name: item
  hosts: node1
  vars:
    users:
      - zhangsan
      - lisi
      - wangwu
  tasks:
    - debug:
       msg: "{{item}}"
      with_items: "{{users}}"

#with_items遍历users里面的元素

第二种写法:
直接在with_items后面写
- name: item
  hosts: node1
  tasks:
    - debug:
       msg: "{{item}}"
      with_items: 
         - zhangsan
         - lisi
         - wangwu
但是这种方式不常用

2:基于字典的循环(with_dict)

就是键值对的方式来进行循环

- name: dict
  hosts: node1
  vars:
    users:
      q1:
       uid: 2022
       name: zhangsan
      q2:
       uid: 2023
       name: lisi
  tasks:
    - debug:
       msg: "{{item.value.name}}"
      with_dict: "{{users}}"

###输出的结果
ok: [node1] => (item={'key': 'q1', 'value': {'uid': 2022, 'name': 'zhangsan'}}) => {
    "msg": "zhangsan"
}
ok: [node1] => (item={'key': 'q2', 'value': {'uid': 2023, 'name': 'lisi'}}) => {
    "msg": "lisi"
}


//思路
key是q1,value是uid,name,然后想要输出什么就以.连接

3:loop循环

天生是用来遍历列表的,但是也可以遍历字典,需要过滤器等

- name: loop
  hosts: node1
  vars:
    users:
      - zhangsan
      - lisi
      - wangwu
  tasks:
    - debug:
       msg: "{{item}}"
      loop: "{{users}}"

 

过滤器等

 

三:总结

when判断有很多的方式来进行判断,facts变量,注册变量,in判断等等

还有几个关键字,block,rescue,always,fail,failed_when

循环语句,最常用的就是loop循环
 

 

热门相关:恐怖复苏   四爷又被福晋套路了   聊斋大圣人   贩罪   天帝龙魂