Loading... <blockquote>在本博客中,ansible是一个系列文章,我们会尽量以通俗易懂的方式总结ansible的相关知识点。 ansible系列博文直达链接:<a href="https://www.zsythink.net/archives/tag/ansible/" target="_blank" rel="noopener">ansible轻松入门系列</a> “ansible系列”中的每篇文章都建立在前文的基础之上,所以,请按照顺序阅读这些文章,否则有可能在阅读中遇到障碍。 </blockquote> 上一篇文章中我们提到过,ansible官网推荐了新的方式操作循环,那么这篇文章中,我就就来聊聊这种新的方式,以便能够更好的从老版本的使用习惯过渡过来。 在2.5版本之前的ansible中,大多数人习惯使用”with_X”风格的关键字操作循环,从2.6版本开始,官方开始推荐使用”loop”关键字代替”with_X”风格的关键字,我们先来看一个小示例,使用loop关键字进行最简单的列表循环,示例如下: <div class="enlighter-default enlighter-v-standard enlighter-t-enlighter enlighter-hover enlighter-overflow-scroll"> <div class="enlighter-toolbar"> <div class="enlighter-btn enlighter-btn-raw"></div> <div class="enlighter-btn enlighter-btn-copy"></div> <div class="enlighter-btn enlighter-btn-window"></div> </div> <div class="enlighter"> <div class=""> <div><span class="enlighter-text">---</span></div> </div> <div class=""> <div><span class="enlighter-text">- hosts: test70</span></div> </div> <div class=""> <div><span class="enlighter-text"> remote_user: root</span></div> </div> <div class=""> <div><span class="enlighter-text"> gather_facts: no</span></div> </div> <div class=""> <div><span class="enlighter-text"> tasks:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - debug:</span></div> </div> <div class=""> <div><span class="enlighter-text"> msg: </span><span class="enlighter-s0">"{{ item }}"</span></div> </div> <div class=""> <div><span class="enlighter-text"> loop:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - teststr1</span></div> </div> <div class=""> <div><span class="enlighter-text"> - teststr2</span></div> </div> </div> </div> 上例使用”loop”关键字,替换了之前总结的”with_list”这种”with_X”风格的关键字,它们的效果是完全相同的。 在总结lookup插件的用法时,已经详细的描述过,我们可以使用”loop”关键字配合对应的”lookup”插件,替换更多的、具有更复杂功能的”with_X”风格的关键字,比如,使用loop关键字和dict插件替换”with_dict”关键字,示例如下 <div class="enlighter-default enlighter-v-standard enlighter-t-enlighter enlighter-hover enlighter-overflow-scroll"> <div class="enlighter-toolbar"> <div class="enlighter-btn enlighter-btn-raw"></div> <div class="enlighter-btn enlighter-btn-copy"></div> <div class="enlighter-btn enlighter-btn-window"></div> </div> <div class="enlighter"> <div class=""> <div><span class="enlighter-text">---</span></div> </div> <div class=""> <div><span class="enlighter-text">- hosts: test70</span></div> </div> <div class=""> <div><span class="enlighter-text"> remote_user: root</span></div> </div> <div class=""> <div><span class="enlighter-text"> gather_facts: no</span></div> </div> <div class=""> <div><span class="enlighter-text"> vars:</span></div> </div> <div class=""> <div><span class="enlighter-text"> users:</span></div> </div> <div class=""> <div><span class="enlighter-text"> alice: female</span></div> </div> <div class=""> <div><span class="enlighter-text"> bob: male</span></div> </div> <div class=""> <div><span class="enlighter-text"> tasks:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - debug:</span></div> </div> <div class=""> <div><span class="enlighter-text"> msg: </span><span class="enlighter-s0">"{{item.key}} is {{item.value}}"</span></div> </div> <div class=""> <div><span class="enlighter-text"> loop: </span><span class="enlighter-s0">"{{ lookup('dict',users) }}"</span></div> </div> </div> </div> 这个示例在上一篇文章中已经解释过,此处不再赘述。 上例使用了”loop加lookup”的方式,完成了循环操作,而在2.6版本的官网手册中,官方开始推荐使用”loop加filter”的方式来替代”loop加lookup”的方式,什么意思呢?我们来看一个小例子,如下: <div class="enlighter-default enlighter-v-standard enlighter-t-enlighter enlighter-hover enlighter-overflow-scroll"> <div class="enlighter-toolbar"> <div class="enlighter-btn enlighter-btn-raw"></div> <div class="enlighter-btn enlighter-btn-copy"></div> <div class="enlighter-btn enlighter-btn-window"></div> </div> <div class="enlighter"> <div class=""> <div><span class="enlighter-text">---</span></div> </div> <div class=""> <div><span class="enlighter-text">- hosts: test70</span></div> </div> <div class=""> <div><span class="enlighter-text"> remote_user: root</span></div> </div> <div class=""> <div><span class="enlighter-text"> gather_facts: no</span></div> </div> <div class=""> <div><span class="enlighter-text"> vars:</span></div> </div> <div class=""> <div><span class="enlighter-text"> users:</span></div> </div> <div class=""> <div><span class="enlighter-text"> alice: female</span></div> </div> <div class=""> <div><span class="enlighter-text"> bob: male</span></div> </div> <div class=""> <div><span class="enlighter-text"> tasks:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - debug:</span></div> </div> <div class=""> <div><span class="enlighter-text"> msg: </span><span class="enlighter-s0">"{{item.key}} is {{item.value}}"</span></div> </div> <div class=""> <div><span class="enlighter-text"> loop: </span><span class="enlighter-s0">"{{ users | dict2items }}"</span></div> </div> </div> </div> 如上例所示,在使用loop关键字操作对应的字典变量users时,并没有借助dict插件,而是借助了一个名为dict2items的过滤器,前文已经总结了过滤器的使用方法,但是并没有介绍dict2items过滤器的用法,那么此处正好介绍一下dict2items过滤器的使用方法,dict2items过滤器是在2.6版本中新加入的过滤器,它可以把一个字典格式的数据进行转换处理,具体会进行怎样的转换处理呢?我们来看个小示例,如下 <div class="enlighter-default enlighter-v-standard enlighter-t-enlighter enlighter-hover enlighter-overflow-scroll"> <div class="enlighter-toolbar"> <div class="enlighter-btn enlighter-btn-raw"></div> <div class="enlighter-btn enlighter-btn-copy"></div> <div class="enlighter-btn enlighter-btn-window"></div> </div> <div class="enlighter"> <div class=""> <div><span class="enlighter-text">users是一个字典格式的变量,它的结构是这样的</span></div> </div> <div class=""> <div><span class="enlighter-text"> users:</span></div> </div> <div class=""> <div><span class="enlighter-text"> alice: female</span></div> </div> <div class=""> <div><span class="enlighter-text"> bob: male</span></div> </div> <div class=""> <div><span class="enlighter-text">当users字典被dict2items转换处理以后,会变成如下模样</span></div> </div> <div class=""> <div><span class="enlighter-text"> users:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - key: alice</span></div> </div> <div class=""> <div><span class="enlighter-text"> value: female</span></div> </div> <div class=""> <div><span class="enlighter-text"> - key: bob</span></div> </div> <div class=""> <div><span class="enlighter-text"> value: male</span></div> </div> </div> </div> 这就是dict2items过滤器的作用,看到上述转换后的数据格式,你是不是觉得似曾相识? 没错,字典数据经过”dict2items”处理后,与字典数据经过”with_dict”处理后的格式完全相同(可以参考前文的”with_dict”总结), 经过上述描述,你应该已经明白了,无论是”with_X”、”loop加lookup”还是”loop加filter”,都是使用不同的方式,实现相同的功能而已,只是在2.6版本的ansible中,官方开始推荐使用”loop加filter”的方式操作循环。 那么我们就来总结一下这种新的使用方式,由于之前已经总结过各种”with_X”关键字的使用方法,所以此处直接列出各种”with_x”关键字对应的新的使用方式。 <h3 id="wznav_0">with_list</h3> <div class="enlighter-default enlighter-v-standard enlighter-t-enlighter enlighter-hover enlighter-overflow-scroll"> <div class="enlighter-toolbar"> <div class="enlighter-btn enlighter-btn-raw"></div> <div class="enlighter-btn enlighter-btn-copy"></div> <div class="enlighter-btn enlighter-btn-window"></div> </div> <div class="enlighter"> <div class=""> <div><span class="enlighter-c0">#loop可以替代with_list,当处理嵌套的列表时,列表不会被拉平</span></div> </div> <div class=""> <div><span class="enlighter-text">---</span></div> </div> <div class=""> <div><span class="enlighter-text">- hosts: test70</span></div> </div> <div class=""> <div><span class="enlighter-text"> remote_user: root</span></div> </div> <div class=""> <div><span class="enlighter-text"> gather_facts: no</span></div> </div> <div class=""> <div><span class="enlighter-text"> vars:</span></div> </div> <div class=""> <div><span class="enlighter-text"> testlist:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - a</span></div> </div> <div class=""> <div><span class="enlighter-text"> - </span><span class="enlighter-g1">[</span><span class="enlighter-text">b,c</span><span class="enlighter-g1">]</span></div> </div> <div class=""> <div><span class="enlighter-text"> - d</span></div> </div> <div class=""> <div><span class="enlighter-text"> tasks:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - debug:</span></div> </div> <div class=""> <div><span class="enlighter-text"> msg: </span><span class="enlighter-s0">"{{item}}"</span></div> </div> <div class=""> <div><span class="enlighter-text"> loop: </span><span class="enlighter-s0">"{{testlist}}"</span></div> </div> </div> </div> <h3 id="wznav_1">with_flattened</h3> <div class="enlighter-default enlighter-v-standard enlighter-t-enlighter enlighter-hover enlighter-overflow-scroll"> <div class="enlighter-toolbar"> <div class="enlighter-btn enlighter-btn-raw"></div> <div class="enlighter-btn enlighter-btn-copy"></div> <div class="enlighter-btn enlighter-btn-window"></div> </div> <div class="enlighter"> <div class=""> <div><span class="enlighter-c0">#flatten过滤器可以替代with_flattened,当处理多层嵌套的列表时,列表中所有的嵌套层级都会被拉平</span></div> </div> <div class=""> <div><span class="enlighter-c0">#示例如下,flatten过滤器的用法在前文中已经总结过,此处不再赘述</span></div> </div> <div class=""> <div><span class="enlighter-text">---</span></div> </div> <div class=""> <div><span class="enlighter-text">- hosts: test70</span></div> </div> <div class=""> <div><span class="enlighter-text"> remote_user: root</span></div> </div> <div class=""> <div><span class="enlighter-text"> gather_facts: no</span></div> </div> <div class=""> <div><span class="enlighter-text"> vars:</span></div> </div> <div class=""> <div><span class="enlighter-text"> testlist:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - a</span></div> </div> <div class=""> <div><span class="enlighter-text"> - </span><span class="enlighter-g1">[</span><span class="enlighter-text">b,c</span><span class="enlighter-g1">]</span></div> </div> <div class=""> <div><span class="enlighter-text"> - d</span></div> </div> <div class=""> <div><span class="enlighter-text"> tasks:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - debug:</span></div> </div> <div class=""> <div><span class="enlighter-text"> msg: </span><span class="enlighter-s0">"{{item}}"</span></div> </div> <div class=""> <div><span class="enlighter-text"> loop: </span><span class="enlighter-s0">"{{testlist | flatten}}"</span></div> </div> </div> </div> <h3 id="wznav_2">with_items</h3> <div class="enlighter-default enlighter-v-standard enlighter-t-enlighter enlighter-hover enlighter-overflow-scroll"> <div class="enlighter-toolbar"> <div class="enlighter-btn enlighter-btn-raw"></div> <div class="enlighter-btn enlighter-btn-copy"></div> <div class="enlighter-btn enlighter-btn-window"></div> </div> <div class="enlighter"> <div class=""> <div><span class="enlighter-c0">#flatten过滤器(加参数)可以替代with_items,当处理多层嵌套的列表时,只有列表中的第一层会被拉平</span></div> </div> <div class=""> <div><span class="enlighter-text">---</span></div> </div> <div class=""> <div><span class="enlighter-text">- hosts: test70</span></div> </div> <div class=""> <div><span class="enlighter-text"> remote_user: root</span></div> </div> <div class=""> <div><span class="enlighter-text"> gather_facts: no</span></div> </div> <div class=""> <div><span class="enlighter-text"> vars:</span></div> </div> <div class=""> <div><span class="enlighter-text"> testlist:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - a</span></div> </div> <div class=""> <div><span class="enlighter-text"> - </span><span class="enlighter-g1">[</span><span class="enlighter-text">b,c</span><span class="enlighter-g1">]</span></div> </div> <div class=""> <div><span class="enlighter-text"> - d</span></div> </div> <div class=""> <div><span class="enlighter-text"> tasks:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - debug:</span></div> </div> <div class=""> <div><span class="enlighter-text"> msg: </span><span class="enlighter-s0">"{{item}}"</span></div> </div> <div class=""> <div><span class="enlighter-text"> loop: </span><span class="enlighter-s0">"{{testlist | flatten(levels=1)}}"</span></div> </div> </div> </div> 直到当前版本的ansible(2.6.2版—2.6.5版),当flatten过滤器配置leves参数处理多层列表时,存在bug 但是为了尽快熟悉新的使用方式,我们暂且忽略这个bug,具体bug可以参考如下链接 <a href="https://www.zsythink.net/wp-content/themes/zibll/go.php?url=aHR0cHM6Ly9naXRodWIuY29tL2Fuc2libGUvYW5zaWJsZS9pc3N1ZXMvNDYzNDM=" target="_blank" rel="noopener">https://github.com/ansible/ansible/issues/46343</a> <h3 id="wznav_3">with_indexed_items</h3> <div class="enlighter-default enlighter-v-standard enlighter-t-enlighter enlighter-hover enlighter-overflow-scroll"> <div class="enlighter-toolbar"> <div class="enlighter-btn enlighter-btn-raw"></div> <div class="enlighter-btn enlighter-btn-copy"></div> <div class="enlighter-btn enlighter-btn-window"></div> </div> <div class="enlighter"> <div class=""> <div><span class="enlighter-c0">#flatten过滤器(加参数),再配合loop_control关键字,可以替代with_indexed_items</span></div> </div> <div class=""> <div><span class="enlighter-c0">#当处理多层嵌套的列表时,只有列表中的第一层会被拉平,flatten过滤器的bug暂且忽略</span></div> </div> <div class=""> <div><span class="enlighter-c0">#示例如下,之后会对示例进行解释</span></div> </div> <div class=""> <div><span class="enlighter-text">---</span></div> </div> <div class=""> <div><span class="enlighter-text">- hosts: test70</span></div> </div> <div class=""> <div><span class="enlighter-text"> remote_user: root</span></div> </div> <div class=""> <div><span class="enlighter-text"> gather_facts: no</span></div> </div> <div class=""> <div><span class="enlighter-text"> vars:</span></div> </div> <div class=""> <div><span class="enlighter-text"> testlist:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - a</span></div> </div> <div class=""> <div><span class="enlighter-text"> - </span><span class="enlighter-g1">[</span><span class="enlighter-text">b,c</span><span class="enlighter-g1">]</span></div> </div> <div class=""> <div><span class="enlighter-text"> - d</span></div> </div> <div class=""> <div><span class="enlighter-text"> tasks:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - debug:</span></div> </div> <div class=""> <div><span class="enlighter-text"> msg: </span><span class="enlighter-s0">"{{index}}--{{item}}"</span></div> </div> <div class=""> <div><span class="enlighter-text"> loop: </span><span class="enlighter-s0">"{{testlist | flatten(levels=1)}}"</span></div> </div> <div class=""> <div><span class="enlighter-text"> loop_control:</span></div> </div> <div class=""> <div><span class="enlighter-text"> index_var: index</span></div> </div> </div> </div> “loop_control”关键字可以用于控制循环的行为,比如在循环时获取到元素的索引。 “index_var”是”loop_control”的一个设置选项,”index_var”的作用是让我们指定一个变量,”loop_control”会将列表元素的索引值存放到这个指定的变量中,比如如下配置 <div class="enlighter-default enlighter-v-standard enlighter-t-enlighter enlighter-hover enlighter-overflow-scroll"> <div class="enlighter-toolbar"> <div class="enlighter-btn enlighter-btn-raw"></div> <div class="enlighter-btn enlighter-btn-copy"></div> <div class="enlighter-btn enlighter-btn-window"></div> </div> <div class="enlighter"> <div class=""> <div><span class="enlighter-text"> loop_control:</span></div> </div> <div class=""> <div><span class="enlighter-text"> index_var: my_idx</span></div> </div> </div> </div> 上述设置表示,在遍历列表时,当前被遍历元素的索引会被放置到”my_idx”变量中,也就是说,当进行循环操作时,只要获取到”my_idx”变量的值,就能获取到当前元素的索引值,当然,除了”index_var”选项,”loop_control”还有一些其他的选项可以使用,我们之后再进行总结。 <h3 id="wznav_4">with_together</h3> <div class="enlighter-default enlighter-v-standard enlighter-t-enlighter enlighter-hover enlighter-overflow-scroll"> <div class="enlighter-toolbar"> <div class="enlighter-btn enlighter-btn-raw"></div> <div class="enlighter-btn enlighter-btn-copy"></div> <div class="enlighter-btn enlighter-btn-window"></div> </div> <div class="enlighter"> <div class=""> <div><span class="enlighter-c0">#zip_longest过滤器配合list过滤器,可以替代with_together</span></div> </div> <div class=""> <div><span class="enlighter-text">---</span></div> </div> <div class=""> <div><span class="enlighter-text">- hosts: test70</span></div> </div> <div class=""> <div><span class="enlighter-text"> remote_user: root</span></div> </div> <div class=""> <div><span class="enlighter-text"> gather_facts: no</span></div> </div> <div class=""> <div><span class="enlighter-text"> vars:</span></div> </div> <div class=""> <div><span class="enlighter-text"> testlist1: </span><span class="enlighter-g1">[</span><span class="enlighter-text"> a, b </span><span class="enlighter-g1">]</span></div> </div> <div class=""> <div><span class="enlighter-text"> testlist2: </span><span class="enlighter-g1">[</span> <span class="enlighter-n1">1</span><span class="enlighter-text">, </span><span class="enlighter-n1">2</span><span class="enlighter-text">, </span><span class="enlighter-n1">3</span> <span class="enlighter-g1">]</span></div> </div> <div class=""> <div><span class="enlighter-text"> testlist3: </span><span class="enlighter-g1">[</span><span class="enlighter-text"> A, B, C, D </span><span class="enlighter-g1">]</span></div> </div> <div class=""> <div><span class="enlighter-text"> tasks:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - debug:</span></div> </div> <div class=""> <div><span class="enlighter-text"> msg: </span><span class="enlighter-s0">"{{ item.0 }} - {{ item.1 }} - {{item.2}}"</span></div> </div> <div class=""> <div><span class="enlighter-text"> with_together:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - </span><span class="enlighter-s0">"{{testlist1}}"</span></div> </div> <div class=""> <div><span class="enlighter-text"> - </span><span class="enlighter-s0">"{{testlist2}}"</span></div> </div> <div class=""> <div><span class="enlighter-text"> - </span><span class="enlighter-s0">"{{testlist3}}"</span></div> </div> <div class=""> <div><span class="enlighter-text"> - debug:</span></div> </div> <div class=""> <div><span class="enlighter-text"> msg: </span><span class="enlighter-s0">"{{ item.0 }} - {{ item.1 }} - {{item.2}}"</span></div> </div> <div class=""> <div><span class="enlighter-text"> loop: </span><span class="enlighter-s0">"{{ testlist1 | zip_longest(testlist2,testlist3) | list }}"</span></div> </div> </div> </div> 上例同时写出了”with_together”和对应的新方式的使用方法,以便进行对比。 当多个列表使用”with_together”进行对齐合并时,如果多个列表的长度不同,则使用最长的列表长度进行对齐,由于短列表中的元素数量不够,所以使用”空值”与长列表中的元素进行对齐,zip_longest过滤器也会像”with_together”一样,对列表进行组合,但是还需要借助list过滤器,将组合后的数据列表化,list过滤器的用法已经总结过,如果你忘了,可以回顾前文,当使用zip_longest过滤器代替with_together关键字时,默认也是使用”空值”与长列表中的元素进行对齐,但是也可以指定其他字符串代替”空值”,示例如下,表示使用”NoEle”代替”空值”,与长列表中的更多的元素进行对齐。 <div class="enlighter-default enlighter-v-standard enlighter-t-enlighter enlighter-hover enlighter-overflow-scroll"> <div class="enlighter-toolbar"> <div class="enlighter-btn enlighter-btn-raw"></div> <div class="enlighter-btn enlighter-btn-copy"></div> <div class="enlighter-btn enlighter-btn-window"></div> </div> <div class="enlighter"> <div class=""> <div><span class="enlighter-text"> - debug:</span></div> </div> <div class=""> <div><span class="enlighter-text"> msg: </span><span class="enlighter-s0">"{{ item.0 }} - {{ item.1 }} - {{item.2}}"</span></div> </div> <div class=""> <div><span class="enlighter-text"> loop: </span><span class="enlighter-s0">"{{ testlist1 | zip_longest(testlist2,testlist3,fillvalue='NoEle') | list }}"</span></div> </div> </div> </div> 从zip_longest过滤器的名字就可以看出,这个过滤器也是使用最长的列表长度进行对齐的,当多个列表的长度不同时,能不能使用最短的列表长度进行对齐呢?没问题,我们只需要借助另一个过滤器即可,这个过滤器的名字是”zip”,示例如下 <div class="enlighter-default enlighter-v-standard enlighter-t-enlighter enlighter-hover enlighter-overflow-scroll"> <div class="enlighter-toolbar"> <div class="enlighter-btn enlighter-btn-raw"></div> <div class="enlighter-btn enlighter-btn-copy"></div> <div class="enlighter-btn enlighter-btn-window"></div> </div> <div class="enlighter"> <div class=""> <div><span class="enlighter-text"> - debug:</span></div> </div> <div class=""> <div><span class="enlighter-text"> msg: </span><span class="enlighter-s0">"{{ item.0 }} - {{ item.1 }} - {{item.2}}"</span></div> </div> <div class=""> <div><span class="enlighter-text"> loop: </span><span class="enlighter-s0">"{{ testlist1 | zip(testlist2,testlist3) | list }}"</span></div> </div> </div> </div> zip_longest和zip过滤器在2.3以及以后的版本中可用。 <h3 id="wznav_5">with_nested/with_cartesian</h3> <div class="enlighter-default enlighter-v-standard enlighter-t-enlighter enlighter-hover enlighter-overflow-scroll"> <div class="enlighter-toolbar"> <div class="enlighter-btn enlighter-btn-raw"></div> <div class="enlighter-btn enlighter-btn-copy"></div> <div class="enlighter-btn enlighter-btn-window"></div> </div> <div class="enlighter"> <div class=""> <div><span class="enlighter-c0">#product过滤器配合list过滤器,可以替代with_nested和with_cartesian</span></div> </div> <div class=""> <div><span class="enlighter-c0">#如果你忘了with_nested和with_cartesian的用法,可以回顾前文</span></div> </div> <div class=""> <div><span class="enlighter-text">---</span></div> </div> <div class=""> <div><span class="enlighter-text">- hosts: test70</span></div> </div> <div class=""> <div><span class="enlighter-text"> remote_user: root</span></div> </div> <div class=""> <div><span class="enlighter-text"> gather_facts: no</span></div> </div> <div class=""> <div><span class="enlighter-text"> vars:</span></div> </div> <div class=""> <div><span class="enlighter-text"> testlist1: </span><span class="enlighter-g1">[</span><span class="enlighter-text"> a, b, c </span><span class="enlighter-g1">]</span></div> </div> <div class=""> <div><span class="enlighter-text"> testlist2: </span><span class="enlighter-g1">[</span> <span class="enlighter-n1">1</span><span class="enlighter-text">, </span><span class="enlighter-n1">2</span><span class="enlighter-text">, </span><span class="enlighter-n1">3</span><span class="enlighter-text">, </span><span class="enlighter-n1">4</span> <span class="enlighter-g1">]</span></div> </div> <div class=""> <div><span class="enlighter-text"> tasks:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - debug:</span></div> </div> <div class=""> <div><span class="enlighter-text"> msg: </span><span class="enlighter-s0">"{{ item.0 }}--{{ item.1 }}"</span></div> </div> <div class=""> <div><span class="enlighter-text"> loop: </span><span class="enlighter-s0">"{{ testlist1 | product(testlist2) | list }}"</span></div> </div> </div> </div> product过滤器也需要将组合后的数据进行列表化,所以需要借助list过滤器 <h3 id="wznav_6">with_sequence</h3> <div class="enlighter-default enlighter-v-standard enlighter-t-enlighter enlighter-hover enlighter-overflow-scroll"> <div class="enlighter-toolbar"> <div class="enlighter-btn enlighter-btn-raw"></div> <div class="enlighter-btn enlighter-btn-copy"></div> <div class="enlighter-btn enlighter-btn-window"></div> </div> <div class="enlighter"> <div class=""> <div><span class="enlighter-c0">#range过滤器配合list过滤器可以代替with_sequence</span></div> </div> <div class=""> <div><span class="enlighter-c0">#你可以先回顾一下with_sequence的用法,然后再测试如下示例</span></div> </div> <div class=""> <div><span class="enlighter-text">---</span></div> </div> <div class=""> <div><span class="enlighter-text">- hosts: test70</span></div> </div> <div class=""> <div><span class="enlighter-text"> remote_user: root</span></div> </div> <div class=""> <div><span class="enlighter-text"> gather_facts: no</span></div> </div> <div class=""> <div><span class="enlighter-text"> tasks:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - debug:</span></div> </div> <div class=""> <div><span class="enlighter-text"> msg: </span><span class="enlighter-s0">"{{item}}"</span></div> </div> <div class=""> <div><span class="enlighter-text"> loop: </span><span class="enlighter-s0">"{{ range(0, 6, 2) | list }}"</span></div> </div> </div> </div> 上例表示生成数字,数字从0开始,到6结束,步长为2,但是rangge函数的操作范围不会包含结束范围,也就是说不会包含6,换句话说就是,上例会生成0、2、4三个数字,而不会包含6,在总结with_sequence时我们提到过,with_sequence还有格式化的功能,比如如下示例 <div class="enlighter-default enlighter-v-standard enlighter-t-enlighter enlighter-hover enlighter-overflow-scroll"> <div class="enlighter-toolbar"> <div class="enlighter-btn enlighter-btn-raw"></div> <div class="enlighter-btn enlighter-btn-copy"></div> <div class="enlighter-btn enlighter-btn-window"></div> </div> <div class="enlighter"> <div class=""> <div><span class="enlighter-text"> - debug:</span></div> </div> <div class=""> <div><span class="enlighter-text"> msg: </span><span class="enlighter-s0">"{{item}}"</span></div> </div> <div class=""> <div><span class="enlighter-text"> with_sequence: start=</span><span class="enlighter-n1">2</span> <span class="enlighter-k1">end</span><span class="enlighter-text">=</span><span class="enlighter-n1">6</span><span class="enlighter-text"> stride=</span><span class="enlighter-n1">2</span><span class="enlighter-text"> format=</span><span class="enlighter-s0">"number is %0.2f"</span></div> </div> </div> </div> 如果你想要使用新的方式实现上例的效果,还需要配合format过滤器一起使用,示例如下 <div class="enlighter-default enlighter-v-standard enlighter-t-enlighter enlighter-hover enlighter-overflow-scroll"> <div class="enlighter-toolbar"> <div class="enlighter-btn enlighter-btn-raw"></div> <div class="enlighter-btn enlighter-btn-copy"></div> <div class="enlighter-btn enlighter-btn-window"></div> </div> <div class="enlighter"> <div class=""> <div><span class="enlighter-text"> - debug:</span></div> </div> <div class=""> <div><span class="enlighter-text"> msg: </span><span class="enlighter-s0">"{{ 'number is %0.2f' | format(item) }}"</span></div> </div> <div class=""> <div><span class="enlighter-text"> loop: </span><span class="enlighter-s0">"{{ range(2, 7, 2) | list }}"</span></div> </div> </div> </div> <h3 id="wznav_7">with_random_choice</h3> <div class="enlighter-default enlighter-v-standard enlighter-t-enlighter enlighter-hover enlighter-overflow-scroll"> <div class="enlighter-toolbar"> <div class="enlighter-btn enlighter-btn-raw"></div> <div class="enlighter-btn enlighter-btn-copy"></div> <div class="enlighter-btn enlighter-btn-window"></div> </div> <div class="enlighter"> <div class=""> <div><span class="enlighter-c0">#使用random函数可以替代with_random_choice,由于random函数是随机取出列表中的一个值,并不涉及循环操作,所以并不用使用loop关键字。</span></div> </div> <div class=""> <div><span class="enlighter-text">---</span></div> </div> <div class=""> <div><span class="enlighter-text">- hosts: test70</span></div> </div> <div class=""> <div><span class="enlighter-text"> remote_user: root</span></div> </div> <div class=""> <div><span class="enlighter-text"> gather_facts: no</span></div> </div> <div class=""> <div><span class="enlighter-text"> vars:</span></div> </div> <div class=""> <div><span class="enlighter-text"> testlist: </span><span class="enlighter-g1">[</span><span class="enlighter-text"> a, b, c </span><span class="enlighter-g1">]</span></div> </div> <div class=""> <div><span class="enlighter-text"> tasks:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - debug:</span></div> </div> <div class=""> <div><span class="enlighter-text"> msg: </span><span class="enlighter-s0">"{{ testlist | random }}"</span></div> </div> </div> </div> <h3 id="wznav_8">with_dict</h3> <div class="enlighter-default enlighter-v-standard enlighter-t-enlighter enlighter-hover enlighter-overflow-scroll"> <div class="enlighter-toolbar"> <div class="enlighter-btn enlighter-btn-raw"></div> <div class="enlighter-btn enlighter-btn-copy"></div> <div class="enlighter-btn enlighter-btn-window"></div> </div> <div class="enlighter"> <div class=""> <div><span class="enlighter-c0">#除了上文总结的dict2items过滤器,dictsort过滤器也可以替代with_dict</span></div> </div> <div class=""> <div><span class="enlighter-text">---</span></div> </div> <div class=""> <div><span class="enlighter-text">- hosts: test70</span></div> </div> <div class=""> <div><span class="enlighter-text"> remote_user: root</span></div> </div> <div class=""> <div><span class="enlighter-text"> gather_facts: no</span></div> </div> <div class=""> <div><span class="enlighter-text"> vars:</span></div> </div> <div class=""> <div><span class="enlighter-text"> users:</span></div> </div> <div class=""> <div><span class="enlighter-text"> d: daisy</span></div> </div> <div class=""> <div><span class="enlighter-text"> c: carol</span></div> </div> <div class=""> <div><span class="enlighter-text"> a: alice</span></div> </div> <div class=""> <div><span class="enlighter-text"> b: bob</span></div> </div> <div class=""> <div><span class="enlighter-text"> e: ella</span></div> </div> <div class=""> <div><span class="enlighter-text"> tasks:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - debug:</span></div> </div> <div class=""> <div><span class="enlighter-text"> msg: </span><span class="enlighter-s0">"{{item.key}} -- {{item.value}}"</span></div> </div> <div class=""> <div><span class="enlighter-text"> loop: </span><span class="enlighter-s0">"{{ users | dict2items }}"</span></div> </div> <div class=""> <div><span class="enlighter-text"> - debug:</span></div> </div> <div class=""> <div><span class="enlighter-text"> msg: </span><span class="enlighter-s0">"{{item.0}} -- {{item.1}}"</span></div> </div> <div class=""> <div><span class="enlighter-text"> loop: </span><span class="enlighter-s0">"{{ users | dictsort }}"</span></div> </div> </div> </div> 正如dictsort的名字一样,dictsort具有排序功能,dictsort会根据键名的字母顺序进行排序 <h3 id="wznav_9">with_subelements</h3> <div class="enlighter-default enlighter-v-standard enlighter-t-enlighter enlighter-hover enlighter-overflow-scroll"> <div class="enlighter-toolbar"> <div class="enlighter-btn enlighter-btn-raw"></div> <div class="enlighter-btn enlighter-btn-copy"></div> <div class="enlighter-btn enlighter-btn-window"></div> </div> <div class="enlighter"> <div class=""> <div><span class="enlighter-c0">#subelements过滤器可以替代with_subelements</span></div> </div> <div class=""> <div><span class="enlighter-text">---</span></div> </div> <div class=""> <div><span class="enlighter-text">- hosts: test70</span></div> </div> <div class=""> <div><span class="enlighter-text"> remote_user: root</span></div> </div> <div class=""> <div><span class="enlighter-text"> gather_facts: no</span></div> </div> <div class=""> <div><span class="enlighter-text"> vars:</span></div> </div> <div class=""> <div><span class="enlighter-text"> users:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - name: bob</span></div> </div> <div class=""> <div><span class="enlighter-text"> gender: male</span></div> </div> <div class=""> <div><span class="enlighter-text"> hobby:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - Skateboard</span></div> </div> <div class=""> <div><span class="enlighter-text"> - VideoGame</span></div> </div> <div class=""> <div><span class="enlighter-text"> - name: alice</span></div> </div> <div class=""> <div><span class="enlighter-text"> gender: female</span></div> </div> <div class=""> <div><span class="enlighter-text"> hobby:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - Music</span></div> </div> <div class=""> <div><span class="enlighter-text"> tasks:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - debug:</span></div> </div> <div class=""> <div><span class="enlighter-text"> msg: </span><span class="enlighter-s0">"{{item.0.name}}'s hobby is {{item.1}}"</span></div> </div> <div class=""> <div><span class="enlighter-text"> with_subelements:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - </span><span class="enlighter-s0">"{{users}}"</span></div> </div> <div class=""> <div><span class="enlighter-text"> - hobby</span></div> </div> <div class=""> <div><span class="enlighter-text"> - debug:</span></div> </div> <div class=""> <div><span class="enlighter-text"> msg: </span><span class="enlighter-s0">"{{item.0.name}}'s hobby is {{item.1}}"</span></div> </div> <div class=""> <div><span class="enlighter-text"> loop: </span><span class="enlighter-s0">"{{users | subelements('hobby')}}"</span></div> </div> </div> </div> 参考之前总结的with_subelements的用法,会更有利于理解上述示例 <h2 id="wznav_10">loop_control</h2> 在介绍使用新的方式替换”with_indexed_items”时,我们已经初步的接触到了loop_control关键字,它可以用于控制循环的行为,比如,使用loop_control的index_var选项,就能在遍历列表时,将元素对应的索引写入到指定的变量中,除了index_var选项,loop_control还有一些其他的选项可用,此处我们就来总结一下这些选项。 <h3 id="wznav_11">pause选项</h3> pause选项能够让我们设置每次循环之后的暂停时间,以秒为单位,换句话说就是设置每次循环之间的间隔时间,示例如下 <div class="enlighter-default enlighter-v-standard enlighter-t-enlighter enlighter-hover enlighter-overflow-scroll"> <div class="enlighter-toolbar"> <div class="enlighter-btn enlighter-btn-raw"></div> <div class="enlighter-btn enlighter-btn-copy"></div> <div class="enlighter-btn enlighter-btn-window"></div> </div> <div class="enlighter"> <div class=""> <div><span class="enlighter-text">---</span></div> </div> <div class=""> <div><span class="enlighter-text">- hosts: test70</span></div> </div> <div class=""> <div><span class="enlighter-text"> remote_user: root</span></div> </div> <div class=""> <div><span class="enlighter-text"> gather_facts: no</span></div> </div> <div class=""> <div><span class="enlighter-text"> tasks:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - debug:</span></div> </div> <div class=""> <div><span class="enlighter-text"> msg: </span><span class="enlighter-s0">"{{item}}"</span></div> </div> <div class=""> <div><span class="enlighter-text"> loop:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - </span><span class="enlighter-n1">1</span></div> </div> <div class=""> <div><span class="enlighter-text"> - </span><span class="enlighter-n1">2</span></div> </div> <div class=""> <div><span class="enlighter-text"> - </span><span class="enlighter-n1">3</span></div> </div> <div class=""> <div><span class="enlighter-text"> loop_control:</span></div> </div> <div class=""> <div><span class="enlighter-text"> pause: </span><span class="enlighter-n1">10</span></div> </div> </div> </div> 上例表示每次循环之间间隔10秒 <h3 id="wznav_12">label选项</h3> 我们先不解释label选项的作用,我们先来看一个小示例,如下 <div class="enlighter-default enlighter-v-standard enlighter-t-enlighter enlighter-hover enlighter-overflow-scroll"> <div class="enlighter-toolbar"> <div class="enlighter-btn enlighter-btn-raw"></div> <div class="enlighter-btn enlighter-btn-copy"></div> <div class="enlighter-btn enlighter-btn-window"></div> </div> <div class="enlighter"> <div class=""> <div><span class="enlighter-text">---</span></div> </div> <div class=""> <div><span class="enlighter-text">- hosts: test70</span></div> </div> <div class=""> <div><span class="enlighter-text"> remote_user: root</span></div> </div> <div class=""> <div><span class="enlighter-text"> gather_facts: no</span></div> </div> <div class=""> <div><span class="enlighter-text"> vars:</span></div> </div> <div class=""> <div><span class="enlighter-text"> users:</span></div> </div> <div class=""> <div><span class="enlighter-text"> alice:</span></div> </div> <div class=""> <div><span class="enlighter-text"> name: Alice Appleworth</span></div> </div> <div class=""> <div><span class="enlighter-text"> gender: female</span></div> </div> <div class=""> <div><span class="enlighter-text"> telephone: </span><span class="enlighter-n1">123</span><span class="enlighter-text">-</span><span class="enlighter-n1">456</span><span class="enlighter-text">-</span><span class="enlighter-n1">7890</span></div> </div> <div class=""> <div><span class="enlighter-text"> bob:</span></div> </div> <div class=""> <div><span class="enlighter-text"> name: Bob Bananarama</span></div> </div> <div class=""> <div><span class="enlighter-text"> gender: male</span></div> </div> <div class=""> <div><span class="enlighter-text"> telephone: </span><span class="enlighter-n1">987</span><span class="enlighter-text">-</span><span class="enlighter-n1">654</span><span class="enlighter-text">-</span><span class="enlighter-n1">3210</span></div> </div> <div class=""> <div><span class="enlighter-text"> tasks:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - debug:</span></div> </div> <div class=""> <div><span class="enlighter-text"> msg: </span><span class="enlighter-s0">"{{item.key}}"</span></div> </div> <div class=""> <div><span class="enlighter-text"> loop: </span><span class="enlighter-s0">"{{users | dict2items}}"</span></div> </div> </div> </div> 执行上例playbook,执行结果如下 <img class=" lazyloaded" src="https://www.zsythink.net/wp-content/uploads/2018/10/100718_1234_1.png" alt="" data-src="https://www.zsythink.net/wp-content/uploads/2018/10/100718_1234_1.png" style=""> 从上图可以看出,我们真正需要的部分就是上图中红线标注的部分,也就是debug模块输出的msg信息,上图中蓝线标注的部分我们可能并不关注,但是当我们使用debug模块输出msg信息时,无论我们是否需要获取整个item的信息,debug模块都会将item的整个信息显示出来,当我们处理的数据越复杂,显示的item的信息就越多,显示在屏幕上的、我们不关注的信息就会越多,怎样改善这种情况呢?借助label选项就行了,来看一个小示例: <div class="enlighter-default enlighter-v-standard enlighter-t-enlighter enlighter-hover enlighter-overflow-scroll"> <div class="enlighter-toolbar"> <div class="enlighter-btn enlighter-btn-raw"></div> <div class="enlighter-btn enlighter-btn-copy"></div> <div class="enlighter-btn enlighter-btn-window"></div> </div> <div class="enlighter"> <div class=""> <div><span class="enlighter-text">---</span></div> </div> <div class=""> <div><span class="enlighter-text">- hosts: test70</span></div> </div> <div class=""> <div><span class="enlighter-text"> remote_user: root</span></div> </div> <div class=""> <div><span class="enlighter-text"> gather_facts: no</span></div> </div> <div class=""> <div><span class="enlighter-text"> vars:</span></div> </div> <div class=""> <div><span class="enlighter-text"> users:</span></div> </div> <div class=""> <div><span class="enlighter-text"> alice:</span></div> </div> <div class=""> <div><span class="enlighter-text"> name: Alice Appleworth</span></div> </div> <div class=""> <div><span class="enlighter-text"> gender: female</span></div> </div> <div class=""> <div><span class="enlighter-text"> telephone: </span><span class="enlighter-n1">123</span><span class="enlighter-text">-</span><span class="enlighter-n1">456</span><span class="enlighter-text">-</span><span class="enlighter-n1">7890</span></div> </div> <div class=""> <div><span class="enlighter-text"> bob:</span></div> </div> <div class=""> <div><span class="enlighter-text"> name: Bob Bananarama</span></div> </div> <div class=""> <div><span class="enlighter-text"> gender: male</span></div> </div> <div class=""> <div><span class="enlighter-text"> telephone: </span><span class="enlighter-n1">987</span><span class="enlighter-text">-</span><span class="enlighter-n1">654</span><span class="enlighter-text">-</span><span class="enlighter-n1">3210</span></div> </div> <div class=""> <div><span class="enlighter-text"> tasks:</span></div> </div> <div class=""> <div><span class="enlighter-text"> - debug:</span></div> </div> <div class=""> <div><span class="enlighter-text"> msg: </span><span class="enlighter-s0">"{{item.key}}"</span></div> </div> <div class=""> <div><span class="enlighter-text"> loop: </span><span class="enlighter-s0">"{{users | dict2items}}"</span></div> </div> <div class=""> <div><span class="enlighter-text"> loop_control:</span></div> </div> <div class=""> <div><span class="enlighter-text"> label: </span><span class="enlighter-s0">"{{item.key}}"</span></div> </div> </div> </div> 上述示例与之前的示例的不同之处在于使用了loop_control关键字,并且使用了label选项,label的值为item.key,与msg的值完全相同,那么,执行上例playbook,结果如下 <img class=" lazyloaded" src="https://www.zsythink.net/wp-content/uploads/2018/10/100718_1234_2.png" alt="" data-src="https://www.zsythink.net/wp-content/uploads/2018/10/100718_1234_2.png" style=""> 正如你所看到的,整个输出信息变得简洁了,item的信息并没有完全显示出来,而是只显示出了item.key的值,达到了我们想要的效果,这就是label选项的作用,它可以在循环输出信息时,简化输出item的信息。 <h3 id="wznav_13">loop_var选项</h3> loop_var选项的作用我们暂且先不进行介绍,因为如果想要搞明白loop_var选项的作用,最好先搞明白”include_tasks”的用法,但是由于到目前为止,我们还没有总结include的相关用法,所以此处暂且放下,等到我们总结include的用法时,再顺势介绍loop_var选项的作用,会更加事半功倍的让我们去理解它。 这篇文章就总结到这里,希望能够对你有所帮助~~ 转载自朱双印日志https://www.zsythink.net/archives/2900 Last modification:May 29, 2024 © Allow specification reprint Like 如果觉得我的文章对你有用,请随意赞赏