Ansible(二十四)-- ansible 中的条件判断 和tests

痛定思痛。 2023-07-20 05:51 160阅读 0赞

ansible 中的条件判断 和tests

  • 条件判断 和tests
    • 判断变量的一些tests
    • 判断执行结果的一些tests
    • 判断路径的一些tests
    • 判断字符串的一些tests
    • 判断整除的一些tests
    • 判断版本号
    • 判断是否子集或父集
    • 判断是否字符串
    • 判断是否数字

条件判断 和tests

在linux中,我们可以使用test命令进行一些常用的判断操作,比如,使用test命令判断”/testdir”是否存在,示例如下

  1. [root@server4 ~]# test -e /testdir
  2. [root@server4 ~]# echo $?
  3. 0
  4. [root@server4 ~]#
  5. [root@server4 ~]# test -e /optt
  6. [root@server4 ~]# echo $?
  7. 1

上述命令表示判断”/testdir”是否存在于系统中,如果”/testdir”存在,则返回true,如果”/testdir”不存在,则返回false,而在linux中,命令的返回值为0表示true,返回值为非0表示false,上例的返回值为0,所以”/testdir”存在于文件系统中,我们也可以在shell脚本中使用test命令进行判断,示例如下

  1. [root@server4 ~]# vim test.sh
  2. [root@server4 ~]# cat test.sh
  3. #!/bin/bash
  4. if test -e /testdir; then
  5. echo "testdir exist"
  6. fi
  7. [root@server4 ~]# sh test.sh
  8. /testdir exist

其实,在ansible中,也有类似的用法,只不过ansible没有使用linux的test命令,而是使用了jinja2的tests,借助tests,我们可以进行一些判断操作,tests会将判断后的布尔值返回,如果条件成立,则返回true,如果条件不成立,tests会返回false,我们通常会在条件判断时使用到tests,那么怎样在ansible中使用jinja2的tests进行判断呢?我们先来看一个小例子,示例如下:

  1. [root@server4 ~]# vim pd5.yml
  2. [root@server4 ~]# cat pd5.yml
  3. ---
  4. - hosts: testB
  5. remote_user: root
  6. gather_facts: no
  7. vars:
  8. testpath: /testdir
  9. tasks:
  10. - debug:
  11. msg: "file exist"
  12. when: testpath is exists

在这里插入图片描述
如上例所示,我们定义了一个testpath变量,这个变量的值是”/testdir”路径,我通过when判断”/testdir”路径是否存在,“is exists”中的”exists”就是tests的一种,它与”test -e”命令的作用是相同的,通过”exists”可以判断ansible主机中的对应路径是否存在(注意:是ansible控制主机中的路径,与目标主机没有关系),当对应的路径存在于ansible控制节点时,”is exists”为真。

“is exists”可以在路径存在时返回真,但是有时,我们想要在路径不存在时返回真,我们可以使用”is not exists”,“is not exists”表示对应路径不存在时返回真,示例如下:

  1. [root@server4 ~]# vim pd5.yml
  2. [root@server4 ~]# cat pd5.yml
  3. ---
  4. - hosts: testB
  5. remote_user: root
  6. gather_facts: no
  7. vars:
  8. testpath: /testdirrr
  9. tasks:
  10. - debug:
  11. msg: "file not exist"
  12. when: testpath is not exists

在这里插入图片描述
我们可以看出,在ansible中,”is exists”表示如果路径存在于ansible节点则返回真,”is not exists”表示如果路径不存在于ansible节点则返回真,当我们使用一种tests进行条件判断时,在tests前面加上”is”进行判断,也可以在tests前面加上”is not”进行取反的判断,当然,在前一篇文章中,我们已经总结了取反的逻辑操作符,所以,我们也可以对整个条件取反,比如如下示例

  1. [root@server4 ~]# vim pd5.yml
  2. [root@server4 ~]# cat pd5.yml
  3. ---
  4. - hosts: testB
  5. remote_user: root
  6. gather_facts: no
  7. vars:
  8. testpath: /testdirrr
  9. tasks:
  10. - debug:
  11. msg: "file not exist"
  12. when: not testpath is exists

在这里插入图片描述

上例取反的效果与”is not”的效果相同。

在ansible中,除了能够使用”exists”这种tests,还有一些别的tests能够使用,我们来认识一下这些tests

判断变量的一些tests

  • defined :判断变量是否已经定义,已经定义则返回真
  • undefind :判断变量是否已经定义,未定义则返回真
  • none :判断变量值是否为空,如果变量已经定义,但是变量值为空,则返回真

上述tests的使用示例如下:

  1. [root@server4 ~]# vim pd6.yml
  2. [root@server4 ~]# cat pd6.yml
  3. ---
  4. - hosts: testB
  5. remote_user: root
  6. gather_facts: no
  7. vars:
  8. testvar: "test"
  9. testvar1:
  10. tasks:
  11. - debug:
  12. msg: "Variable is defined"
  13. when: testvar is defined
  14. - debug:
  15. msg: "Variable is undefined"
  16. when: testvar2 is undefined
  17. - debug:
  18. msg: "The variable is defined, but there is no value"
  19. when: testvar1 is none

当对应的条件为真时,你可以看到debug模块对应的输出:

在这里插入图片描述

判断执行结果的一些tests

  • success 或 succeeded:通过任务的返回信息判断任务的执行状态,任务执行成功则返回真
  • failure 或 failed:通过任务的返回信息判断任务的执行状态,任务执行失败则返回真
  • change 或 changed:通过任务的返回信息判断任务的执行状态,任务执行状态为changed则返回真
  • skip 或 skipped:通过任务的返回信息判断任务的执行状态,当任务没有满足条件,而被跳过执行时,则返回真

上述tests的使用示例如下:

  1. [root@server4 ~]# vim pd7.yml
  2. [root@server4 ~]# cat pd7.yml
  3. ---
  4. - hosts: testB
  5. remote_user: root
  6. gather_facts: no
  7. vars:
  8. doshell: "yes"
  9. tasks:
  10. - shell: "cat /testdir/abc"
  11. when: doshell == "yes"
  12. register: returnmsg
  13. ignore_errors: true
  14. - debug:
  15. msg: "success"
  16. when: returnmsg is success
  17. - debug:
  18. msg: "failed"
  19. when: returnmsg is failure
  20. - debug:
  21. msg: "changed"
  22. when: returnmsg is change
  23. - debug:
  24. msg: "skip"
  25. when: returnmsg is skip

在这里插入图片描述
在这里插入图片描述

如上例所示,我们调用了shell模块,将shell模块的返回信息注册在了returnmsg变量中,之后的debug任务均通过returnmsg变量判断shell模块的执行状态,因为shell模块有可能执行失败,所以,我们为shell模块添加了”ignore_errors: true”,以便即使shell模块执行失败,也能执行后面的任务,并且,我为shell模块添加了判断条件,当不满足条件时,shell模块则会跳过,即不会执行,你可以修改一下条件,以便测试skip的判断效果。

判断路径的一些tests

注:如下tests的判断均针对于ansible主机中的路径,与目标主机无关

  • file : 判断路径是否是一个文件,如果路径是一个文件则返回真
  • directory :判断路径是否是一个目录,如果路径是一个目录则返回真
  • link :判断路径是否是一个软链接,如果路径是一个软链接则返回真
  • mount:判断路径是否是一个挂载点,如果路径是一个挂载点则返回真
  • exists:判断路径是否存在,如果路径存在则返回真

注:上述test名均为2.6版本中的名称,在2.5版本之前某些test需要加上”is_“前缀

上述tests的使用示例如下:

  1. [root@server4 ~]# vim pd8.yml
  2. [root@server4 ~]# cat pd8.yml
  3. ---
  4. - hosts: testB
  5. remote_user: root
  6. gather_facts: no
  7. vars:
  8. testpath1: "/testdir/test"
  9. testpath2: "/testdir/"
  10. testpath3: "/testdir/testsoftlink"
  11. testpath4: "/testdir/testhardlink"
  12. testpath5: "/boot"
  13. tasks:
  14. - debug:
  15. msg: "file"
  16. when: testpath1 is file
  17. - debug:
  18. msg: "directory"
  19. when: testpath2 is directory
  20. - debug:
  21. msg: "link"
  22. when: testpath3 is link
  23. - debug:
  24. msg: "link"
  25. when: testpath4 is link
  26. - debug:
  27. msg: "mount"
  28. when: testpath5 is mount
  29. - debug:
  30. msg: "exists"
  31. when: testpath1 is exists

建立测试文件:

  1. [root@server4 ~]# cd /testdir/
  2. [root@server4 testdir]# touch test
  3. [root@server4 testdir]# ln -s test testsoftlink
  4. [root@server4 testdir]# ln test testhardlink

在这里插入图片描述
playbook运行结果:
在这里插入图片描述在这里插入图片描述
由于testhardlink为硬链接,而is link判断只有为软链接时才会返回真,因此这个task被跳过。

判断字符串的一些tests

  • lower:判断包含字母的字符串中的字母是否是纯小写,字符串中的字母全部为小写则返回真
  • upper:判断包含字母的字符串中的字母是否是纯大写,字符串中的字母全部为大写则返回真

上述tests的使用示例如下:

  1. [root@server4 ~]# vim pd9.yml
  2. [root@server4 ~]# cat pd9.yml
  3. ---
  4. - hosts: testB
  5. remote_user: root
  6. gather_facts: no
  7. vars:
  8. str1: "abc"
  9. str2: "ABC"
  10. tasks:
  11. - debug:
  12. msg: "This string is all lowercase"
  13. when: str1 is lower
  14. - debug:
  15. msg: "This string is all uppercase"
  16. when: str2 is upper

在这里插入图片描述

判断整除的一些tests

  • even :判断数值是否是偶数,是偶数则返回真
  • odd :判断数值是否是奇数,是奇数则返回真
  • divisibleby(num) :判断是否可以整除指定的数值(num),如果除以指定的值以后余数为0,则返回真

上述tests的使用示例如下:

  1. [root@server4 ~]# vim pd10.yml
  2. [root@server4 ~]# cat pd10.yml
  3. ---
  4. - hosts: testB
  5. remote_user: root
  6. gather_facts: no
  7. vars:
  8. num1: 4
  9. num2: 7
  10. num3: 64
  11. tasks:
  12. - debug:
  13. msg: "An even number"
  14. when: num1 is even
  15. - debug:
  16. msg: "An odd number"
  17. when: num2 is odd
  18. - debug:
  19. msg: "Can be divided exactly by"
  20. when: num3 is divisibleby(8)

在这里插入图片描述

判断版本号

  • version:可以用于对比两个版本号的大小,或者与指定的版本号进行对比,使用语法为 version(‘版本号’, ‘比较操作符’)

注:2.5版本中此tests从version_compare更名为version

示例如下

  1. [root@server4 ~]# vim pd11.yml
  2. [root@server4 ~]# cat pd11.yml
  3. ---
  4. - hosts: testB
  5. remote_user: root
  6. vars:
  7. ver: 7.4.1708
  8. ver1: 7.4.1707
  9. tasks:
  10. - debug:
  11. msg: "This message can be displayed when the ver is greater than ver1"
  12. when: ver is version(ver1,">")
  13. - debug:
  14. msg: "system version { {ansible_distribution_version}} greater than 7.2"
  15. when: ansible_distribution_version is version("7.2","gt")

在这里插入图片描述
注:我们使用的系统版本为7.3

上例中有两个task

第一个task中,当ver的版本号大于ver1时,返回真,条件成立,debug模块输出”This message can be displayed when the ver is greater than ver1”

第二个task中,当facts中的ansible_distribution_version的值大于7.2时,返回真,条件成立,debug模块输出对应信息

我们可以发现,”>“与”gt”都表示”大于”,当使用version时,支持多种风格的比较操作符,你可以根据自己的使用习惯进行选择,version支持的比较操作符如下

  1. 大于:>, gt
  2. 大于等于:>=, ge
  3. 小于:<, lt
  4. 小于等于:<=, le
  5. 等于: ==, =, eq
  6. 不等于:!=, <>, ne

判断是否子集或父集

  • subset:判断一个list是不是另一个list的子集,是另一个list的子集时返回真
  • superset : 判断一个list是不是另一个list的父集,是另一个list的父集时返回真

注:2.5版本中上述两个tests从issubset和issuperset更名为subset和superset

示例如下

  1. [root@server4 ~]# vim pd12.yml
  2. [root@server4 ~]# cat pd12.yml
  3. ---
  4. - hosts: testB
  5. remote_user: root
  6. gather_facts: no
  7. vars:
  8. a:
  9. - 2
  10. - 5
  11. b: [1,2,3,4,5]
  12. tasks:
  13. - debug:
  14. msg: "A is a subset of B"
  15. when: a is subset(b)
  16. - debug:
  17. msg: "B is the parent set of A"
  18. when: b is superset(a)

在这里插入图片描述如上图所示,很明显我们可以看出[2,5]是[1,2,3,4,5]的子集。

判断是否字符串

  • string:判断对象是否是一个字符串,是字符串则返回真

    [root@server4 ~]# vim pd13.yml

    [root@server4 ~]# cat pd13.yml

    • hosts: testB
      remote_user: root
      gather_facts: no
      vars:
      testvar1: 1
      testvar2: “1”
      testvar3: a
      tasks:
      • debug:
        msg: “This variable is a string”
        when: testvar1 is string
      • debug:
        msg: “This variable is a string”
        when: testvar2 is string
      • debug:
        msg: “This variable is a string”
        when: testvar3 is string

在这里插入图片描述

上例playbook中只有testvar2(“1”)和testvar3(a)会被判断成字符串,testvar1(1)不会

判断是否数字

  • number:判断对象是否是一个数字,是数字则返回真

示例如下

  1. [root@server4 ~]# vim pd14.yml
  2. [root@server4 ~]# cat pd14.yml
  3. ---
  4. - hosts: testB
  5. remote_user: root
  6. gather_facts: no
  7. vars:
  8. testvar1: 1
  9. testvar2: "1"
  10. testvar3: 00.20
  11. tasks:
  12. - debug:
  13. msg: "This variable is number"
  14. when: testvar1 is number
  15. - debug:
  16. msg: "This variable is a number"
  17. when: testvar2 is number
  18. - debug:
  19. msg: "This variable is a number"
  20. when: testvar3 is number

在这里插入图片描述

上例playbook中只有testvar1(1)和testvar3(00.20)会被判断成数字,testvar2(“1”)不会。

发表评论

表情:
评论列表 (有 0 条评论,160人围观)

还没有评论,来说两句吧...

相关阅读