ansible笔记(27):条件判断与tests

  • A+
所属分类:ansible  运维技术

在本博客中,ansible是一个系列文章,我们会尽量以通俗易懂的方式总结ansible的相关知识点。

ansible系列博文直达链接:ansible轻松入门系列

"ansible系列"中的每篇文章都建立在前文的基础之上,所以,请按照顺序阅读这些文章,否则有可能在阅读中遇到障碍。

 

在写这篇文章时,遇到了一个小bug,经过测试,当前最新版本(2.6.2)的ansible不存在此bug,于是将ansible版本从2.4.2升级到了2.6.2,从这篇文章开始,如果没有特殊说明,演示环境中的ansible的版本为2.6.2.

 

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

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

 

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

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

 

"is exists"可以在路径存在时返回真,但是有时,我们想要在路径不存在时返回真,我们该怎么办呢?我们可以使用"is not exists","is not exists"表示对应路径不存在时返回真,示例如下:

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

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

 

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

 

判断变量的一些tests

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

undefind :判断变量是否已经定义,未定义则返回真

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

 

上述tests的使用示例如下:

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

 

判断执行结果的一些tests

success 或 succeeded:通过任务的返回信息判断任务的执行状态,任务执行成功则返回真

failure 或 failed:通过任务的返回信息判断任务的执行状态,任务执行失败则返回真

change 或 changed:通过任务的返回信息判断任务的执行状态,任务执行状态为changed则返回真

skip 或 skipped:通过任务的返回信息判断任务的执行状态,当任务没有满足条件,而被跳过执行时,则返回真

 

上述tests的使用示例如下:

如上例所示,我们调用了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的使用示例如下:

 

判断字符串的一些tests

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

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

 

上述tests的使用示例如下:

 

判断整除的一些tests

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

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

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

 

上述tests的使用示例如下:

 

其他的一些testst

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

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

示例如下

上例中有两个task

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

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

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

大于:>, gt

大于等于:>=, ge

小于:<, lt

小于等于:<=, le

等于: ==, =, eq

不等于:!=, <>, ne

 


 

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

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

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

示例如下

 


 

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

上例playbook中只有testvar2和testvar3会被判断成字符串,testvar1不会

 


 

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

示例如下

上例playbook中只有testvar1和testvar3会被判断成数字,testvar2不会

 

 

这篇文章就总结到这里,希望能够对你有所帮助~

 

 

weinxin
我的微信公众号
关注"实用运维笔记"微信公众号,当博客中有新文章时,可第一时间得知哦~
朱双印

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

目前评论:5   其中:访客  4   博主  1

    • avatar 朱双印 Admin

      今天看到你们的讨论,都对我进行了肯定,我是很开心的,谢谢drgcaosheng,谢谢怒风 ,怒风、drgcaosheng、echo等等这些经常在博客留言的朋友,关注微信公众号的朋友,还有在QQ群中讨论的这些朋友,你们的认可也一直都是支撑我前进的动力,有你们的支持和鼓励,我相信我的博客会更加长久的,也希望我能和你们一起努力下去,早点实现自己的目标,加油吧,共勉~

      • avatar echo 5

        打卡

        • avatar 怒风 2

          1、很棒的教程!通俗易懂的讲解,耐心细致的描述,还不时流露出一点小幽默,真是博客之中的教科书典范!
          2、其他网站上面一点点技术文档动辄就要收费、注册的,朱老师却能无私的把自己的技术传授给大家,真是令人钦佩敬仰!
          3、linux自动化运维的主流工具,ansible和saltstack,希望朱老师百忙之中抽时间整理一下saltstack的教程,感激不尽!

            • avatar drgcaosheng 4

              @怒风 虽然不想回复进行吐槽,但是为什么看到的一直都是说希望朱老师从百忙之中抽时间整理一下**教程之类的。从来没有说过,**我感觉缺少什么资料的,我提供一下或者我来抽时间写一下。==之类。只想说,博主是无私,将花费大量时间整理出来的资料分享,已经很好了。

                • avatar 怒风 2

                  @drgcaosheng 第一,我确实希望看到saltstack的教程,而且我觉得其他朋友可能也会有自己希望学习到的内容,我们在这里把自己的想法表达出来也没有什么不妥吧,至于吐槽?我目前还只是一个小白,抱歉我暂时真的没有什么成果能和大家分享,但是,我一直在努力的学习,今后如果我能学有所成,也一定和朱老师一样无私地帮助更多的人!
                  第二,在这里留言只是和朱老师或者其他朋友互动交流而已,大家畅所欲言,才能有氛围,大家在朱老师的博客里讨论的热火朝天才好呢。如果每个人说话之前都瞻前顾后担心自己说出去的话是否合适,那么,这里必定死气沉沉,没有人气。我想,这也不是朱老师希望看到的吧。