ansible笔记(20):循环(二)

栏目: 服务器 · 发布时间: 7年前

内容简介:所属分类:ansible
  • A+

所属分类:ansible 运维技术

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

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

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

前文中,我们总结了with_items的用法,你肯定还有印象,前文中有如下两个示例,它们的执行效果是相同的

示例一
---
- hosts: test70
  remote_user: root
  gather_facts: no
  tasks:
  - debug:
      msg: "{{item}}"
    with_items:
    - 1
    - 2
    - 3
 
示例二
---
- hosts: test70
  remote_user: root
  gather_facts: no
  tasks:
  - debug:
      msg: "{{item}}"
    with_items: [ 1, 2, 3 ]

上述两个示例分别使用了不同的语法自定义了一个列表,虽然语法不同,但是最终的效果是相同的,其实,我们可以把上述两种语法结合起来使用,结合后可以定义出稍微复杂一些的结构,比如嵌套的列表(序列中的序列),示例如下

---
- hosts: test70
  remote_user: root
  gather_facts: no
  tasks:
  - debug:
      msg: "{{item}}"
    with_items:
    - [ 1, 2, 3 ]
    - [ a, b ]

上例中我们将之前的两种语法结合,定义出了一个列表,而这个列表中的每一项都是列表,相当于一个大列表中嵌套了多个小列表,那么,当我们使用with_items遍历上述列表时,会是什么样的效果呢?我们试试,执行后的信息如下

TASK [debug] ********************************
ok: [test70] => (item=1) => {
    "changed": false,
    "item": 1,
    "msg": 1
}
ok: [test70] => (item=2) => {
    "changed": false,
    "item": 2,
    "msg": 2
}
ok: [test70] => (item=3) => {
    "changed": false,
    "item": 3,
    "msg": 3
}
ok: [test70] => (item=a) => {
    "changed": false,
    "item": "a",
    "msg": "a"
}
ok: [test70] => (item=b) => {
    "changed": false,
    "item": "b",
    "msg": "b"
}

可以看到,debug模块循环的将每个小列表中的值都输出了一遍,这可能与我们想象的不太一样,因为在之前的示例中, 并没有列表嵌套列表的情况,按照之前的思路,with_items会循环的输出列表(最外层大列表)中的每一项,也就是说,按照之前的思路debug模块应该会将每个小列表作为一个小整体输出,而不应该输出小列表中的每个元素,但是事实却是with_items将嵌套在大列表中的每个小列表都"展开"了,并且将小列表中的元素都输出了,如果,我们想要将每个小列表作为一个整体输出,该怎么办呢?

我们可以使用with_list关键字,替换上例playbook中的with_items关键字,那么with_list关键字与with_items关键字有什么区别呢?将上例的with_items替换成with_list以后又能不能实现我们想要的效果呢?我们一起来试试,示例playbook如下

---
- hosts: test70
  remote_user: root
  gather_facts: no
  tasks:
  - debug:
      msg: "{{item}}"
    with_list:
    - [ 1, 2, 3 ]
    - [ a, b ]

如上例所示,上例playbook中的列表与之前示例playbook中的列表完全相同,都是嵌套的列表,只是将原来的with_items关键字替换为了with_list关键字,那么我们来看一下执行效果,上例playbook执行后debug模块的输出结果如下

TASK [debug] *******************************
ok: [test70] => (item=[1, 2, 3]) => {
    "changed": false,
    "item": [
        1,
        2,
        3
    ],
    "msg": [
        1,
        2,
        3
    ]
}
ok: [test70] => (item=[u'a', u'b']) => {
    "changed": false,
    "item": [
        "a",
        "b"
    ],
    "msg": [
        "a",
        "b"
    ]
}

如上述信息所示,经过with_list处理后,每个嵌套在大列表中的小列表都被当做一个整体存放在item变量中,最终被debug作为一个小整体输出了,而不会像with_items一样将小列表"展开拉平"后一并将小列表中的元素循环输出。

前一篇文章中有很多示例,其实这些示例中的with_items关键字都可以替换成with_list关键字,替换后都可正常执行,这是因为,前一篇文章中的示例中的列表都是简单的单层列表,当处理单层的简单列表时,with_list与with_items没有任何区别,只有在处理上例中的"嵌套列表"时,才会体现出区别,区别就是,with_items会将嵌套在内的小列表"拉平",拉平后循环处理所有元素,而with_list则不会"拉平"嵌套的列表,with_list只会循环的处理列表(最外层列表)中的每一项。

其实,当处理这种嵌套的列表时,如果想要实现"拉平"的效果,我们还能使用另外一个关键字,它就是with_flattened关键字,示例playbook如下:

---
- hosts: test70
  remote_user: root
  gather_facts: no
  tasks:
  - debug:
      msg: "{{item}}"
    with_flattened:
    - [ 1, 2, 3 ]
    - [ a, b ]

执行上例playbook以后,你会发现,执行效果与with_items效果完全相同。

此刻,你一定已经明白了with_list、with_items、with_flattened之间的区别了,在处理简单的单层列表时,他们没有区别,但是当处理嵌套的多层列表时,with_items与with_flattened会将嵌套列表"拉平展开",循环的处理每个元素,而with_list只会处理最外层的列表,将最外层的列表中的每一项循环处理。

话说,我们还能使用如下方法定义嵌套的列表,示例如下:

    with_list:
    -
      - 1
      - 2
      - 3
    -
      - a
      - b

上述方法通过缩进对齐的方式,定义出了一个嵌套有列表的列表,与如下定义完全相同

    with_list:
    - [ 1, 2, 3 ]
    - [ a, b ]

目前为止,我们已经了解到了三个关键字可以用于循环操作,它们是with_list、with_items、with_flattened,那么我们再来认识一个新的关键字,它就是"with_together",with_together可以将两个列表中的元素"对齐合并",单单用语言来描述,不是特别容易理解,不如来看一个小示例,示例playbook如下:

---
- hosts: test70
  remote_user: root
  gather_facts: no
  tasks:
  - debug:
      msg: "{{ item }}"
    with_together:
    - [ 1, 2, 3 ]
    - [ a, b, c ]

如上例所示,我们定义了一个嵌套的列表,大列表内一共有两个小列表,每个小列表内有三个值,然后使用with_together关键字处理这个嵌套列表,上例playbook执行结果如下

TASK [debug] ******************************
ok: [test70] => (item=[1, u'a']) => {
    "changed": false,
    "item": [
        1,
        "a"
    ],
    "msg": [
        1,
        "a"
    ]
}
ok: [test70] => (item=[2, u'b']) => {
    "changed": false,
    "item": [
        2,
        "b"
    ],
    "msg": [
        2,
        "b"
    ]
}
ok: [test70] => (item=[3, u'c']) => {
    "changed": false,
    "item": [
        3,
        "c"
    ],
    "msg": [
        3,
        "c"
    ]
}

从上述结果可以看出:

第一个小列表中的第1个值与第二个小列表中的第1个值合并在一起输出了,

第一个小列表中的第2个值与第二个小列表中的第2个值合并在一起输出了,

第一个小列表中的第3个值与第二个小列表中的第3个值合并在一起输出了,

这就是with_together所谓的"对齐合并"功能,聪明如你一定已经明白了。

不过上例中,两个小列表中的元素数量相同,如果元素数量不同的小列表使用with_together对齐合并,会是什么效果呢?

这里就不进行示例了,快动手试试吧。

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

我的微信公众号

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


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

自己动手做iOS App

自己动手做iOS App

张子怡 / 电子工业出版社 / 2017-8 / 69.00

《自己动手做iOS App:从设计开发到上架App Store》为想要接触iOS 应用设计、开发的读者提供了由浅入深的详细指导。从iOS 应用制作的步骤是什么,应该使用什么软件,如何发布应用到App Store,到iOS 的设计理念是什么,如何正确书写Swift 语言,再到后端和客户端是如何交互运作的等,本书配合图示,精辟、直观地阐明了iOS 应用制作中的种种疑问。 如果你是一位第一次接触i......一起来看看 《自己动手做iOS App》 这本书的介绍吧!

SHA 加密
SHA 加密

SHA 加密工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器