黑帽联盟

 找回密码
 会员注册
查看: 1077|回复: 0
打印 上一主题 下一主题

[基础服务] ansible笔记(24):循环(六)

[复制链接]
yun 黑帽联盟官方人员 

920

主题

37

听众

1364

积分

超级版主

Rank: 8Rank: 8

  • TA的每日心情
    奋斗
    2019-10-18 11:20
  • 签到天数: 678 天

    [LV.9]以坛为家II

    本帖最后由 yun 于 2019-9-11 17:14 编辑

    ansible是一个系列文章,我们会尽量以通俗易懂的方式总结ansible的相关知识点。
    ansible系列博文直达链接:ansible轻松入门系列
    "ansible系列"中的每篇文章都建立在前文的基础之上,所以,请按照顺序阅读这些文章,否则有可能在阅读中遇到障碍。


    老套路,今天继续来认识两个用于循环的关键字,它们是"with_dict"和"with_subelements"

    先聊聊"with_dict",顾名思义,"with_dict"的使用场景应该与"字典"有关,我们先来看一个小例子,结合示例更加容易说明白,示例playbook如下:
    1. ---
    2. - hosts: test70
    3.   remote_user: root
    4.   gather_facts: no
    5.   vars:
    6.     users:
    7.       alice: female
    8.       bob: male
    9.   tasks:
    10.   - debug:
    11.       msg: "{{item}}"
    12.     with_dict: "{{users}}"
    复制代码
    在上例中,我们使用字典的方式定义了users变量,users中一共有两个用户,alice和bob,从变量的键值对可以看出,alice是女性,bob是男性,然后,我们使用"with_dict"关键字处理了这个字典格式的变量,那么我们来看一下执行效果,上例playbook执行后debug模块的输出信息如下:
    1. TASK [debug] *************************************
    2. ok: [test70] => (item={'value': u'male', 'key': u'bob'}) => {
    3.     "changed": false,
    4.     "item": {
    5.         "key": "bob",
    6.         "value": "male"
    7.     },
    8.     "msg": {
    9.         "key": "bob",
    10.         "value": "male"
    11.     }
    12. }
    13. ok: [test70] => (item={'value': u'female', 'key': u'alice'}) => {
    14.     "changed": false,
    15.     "item": {
    16.         "key": "alice",
    17.         "value": "female"
    18.     },
    19.     "msg": {
    20.         "key": "alice",
    21.         "value": "female"
    22.     }
    23. }
    复制代码
    从输出信息可以看出,字典格式的users变量经过"with_dict"处理后,字典中的每个键值对被放到了item变量中,而且,键值对中的"键"被放入了"key"关键字中,键值对中的"值"被放入了"value"关键字中,所以,我们可以通过key关键字和value关键字分别获取到字典中键值对的"键"和"值",示例playbook如下
    1. ---
    2. - hosts: test70
    3.   remote_user: root
    4.   gather_facts: no
    5.   vars:
    6.     users:
    7.       alice: female
    8.       bob: male
    9.   tasks:
    10.   - debug:
    11.       msg: "User name: {{item.key}} , User's gender: {{item.value}} "
    12.     with_dict: "{{users}}"
    复制代码
    上例执行后debug模块输出如下:
    1. TASK [debug] ************************************************
    2. ok: [test70] => (item={'value': u'male', 'key': u'bob'}) => {
    3.     "changed": false,
    4.     "item": {
    5.         "key": "bob",
    6.         "value": "male"
    7.     },
    8.     "msg": "User name: bob , User's gender: male "
    9. }
    10. ok: [test70] => (item={'value': u'female', 'key': u'alice'}) => {
    11.     "changed": false,
    12.     "item": {
    13.         "key": "alice",
    14.         "value": "female"
    15.     },
    16.     "msg": "User name: alice , User's gender: female "
    17. }
    复制代码
    你一定已经明白了"with_dict"的作用,那么我们来扩展一下,将上例中字典格式的变量变得"丰富"一点,示例playbook如下:
    1. ---
    2. - hosts: test70
    3.   remote_user: root
    4.   gather_facts: no
    5.   vars:
    6.     users:
    7.       alice:
    8.         name: Alice Appleworth
    9.         gender: female
    10.         telephone: 123-456-7890
    11.       bob:
    12.         name: Bob Bananarama
    13.         gender: male
    14.         telephone: 987-654-3210
    15.   tasks:
    16.   - debug:
    17.       msg: "{{item}}"
    18.     with_dict: "{{users}}"
    复制代码
    如上例所示,我们将alice和bob的信息完善了,每个人都有自己姓名,性别,电话等信息,上例playbook执行后debug输出信息如下:
    1. TASK [debug] *****************************************
    2. ok: [test70] => (item={'value': {u'gender': u'male', u'name': u'Bob Bananarama', u'telephone': u'987-654-3210'}, 'key': u'bob'}) => {
    3.     "changed": false,
    4.     "item": {
    5.         "key": "bob",
    6.         "value": {
    7.             "gender": "male",
    8.             "name": "Bob Bananarama",
    9.             "telephone": "987-654-3210"
    10.         }
    11.     },
    12.     "msg": {
    13.         "key": "bob",
    14.         "value": {
    15.             "gender": "male",
    16.             "name": "Bob Bananarama",
    17.             "telephone": "987-654-3210"
    18.         }
    19.     }
    20. }
    21. ok: [test70] => (item={'value': {u'gender': u'female', u'name': u'Alice Appleworth', u'telephone': u'123-456-7890'}, 'key': u'alice'}) => {
    22.     "changed": false,
    23.     "item": {
    24.         "key": "alice",
    25.         "value": {
    26.             "gender": "female",
    27.             "name": "Alice Appleworth",
    28.             "telephone": "123-456-7890"
    29.         }
    30.     },
    31.     "msg": {
    32.         "key": "alice",
    33.         "value": {
    34.             "gender": "female",
    35.             "name": "Alice Appleworth",
    36.             "telephone": "123-456-7890"
    37.         }
    38.     }
    39. }
    复制代码
    从输出信息可以看出,gender、name、telephone都被放入了value关键字中,聪明如你一定想到了,这种情况下,如果想要获取到gender、name、telephone的值,则可以使用如下playbook中的方法
    1. ---
    2. - hosts: test70
    3.   remote_user: root
    4.   gather_facts: no
    5.   vars:
    6.     users:
    7.       alice:
    8.         name: Alice Appleworth
    9.         gender: female
    10.         telephone: 123-456-7890
    11.       bob:
    12.         name: Bob Bananarama
    13.         gender: male
    14.         telephone: 987-654-3210
    15.   tasks:
    16.   - debug:
    17.       msg: "User {{ item.key }} is {{ item.value.name }}, Gender: {{ item.value.gender }}, Tel: {{ item.value.telephone }}"
    18.     with_dict: "{{users}}"
    复制代码
    聊完"with_dict",现在来聊聊另一个关键字:"with_subelements",单单靠语言描述"with_subelements"的作用有些麻烦,也不容易理解,不如先来看一个小示例,示例playbook如下:
    1. ---
    2. - hosts: test70
    3.   remote_user: root
    4.   gather_facts: no
    5.   vars:
    6.     users:
    7.     - name: bob
    8.       gender: male
    9.       hobby:
    10.         - Skateboard
    11.         - VideoGame
    12.     - name: alice
    13.       gender: female
    14.       hobby:
    15.         - Music
    16.   tasks:
    17.   - debug:
    18.       msg: "{{ item }}"
    19.     with_subelements:
    20.     - "{{users}}"
    21.     - hobby
    复制代码
    如上例所示,我们定义了一个复合结构的字典变量,users变量,users变量列表中有两个块序列,这两个块序列分别代表两个用户,bob和alice,alice是个妹子,bob是个汉子,bob的爱好是滑板和打游戏,alice的爱好是听音乐,上例中,我们使用"with_subelements"关键字处理了users变量,在处理users变量的同时,还指定了一个属性,"hobby属性",细心如你一定已经发现了,"hobby属性"正是"users"变量中每个用户的"子属性",换句话说,"hobby属性"是users中每个块序列的子元素,而且,hobby属性是一个"键值对",其"值"是一个列表,因为每个人可以有多个爱好,那么经过"with_subelements"处理后,每个item是什么样子的呢?我们来看一下执行效果,执行上例playbook后,debug模块输出如下:
    1. TASK [debug] ***********************************************************
    2. ok: [test70] => (item=({u'gender': u'male', u'name': u'bob'}, u'Skateboard')) => {
    3.     "changed": false,
    4.     "item": [
    5.         {
    6.             "gender": "male",
    7.             "name": "bob"
    8.         },
    9.         "Skateboard"
    10.     ],
    11.     "msg": [
    12.         {
    13.             "gender": "male",
    14.             "name": "bob"
    15.         },
    16.         "Skateboard"
    17.     ]
    18. }
    19. ok: [test70] => (item=({u'gender': u'male', u'name': u'bob'}, u'VideoGame')) => {
    20.     "changed": false,
    21.     "item": [
    22.         {
    23.             "gender": "male",
    24.             "name": "bob"
    25.         },
    26.         "VideoGame"
    27.     ],
    28.     "msg": [
    29.         {
    30.             "gender": "male",
    31.             "name": "bob"
    32.         },
    33.         "VideoGame"
    34.     ]
    35. }
    36. ok: [test70] => (item=({u'gender': u'female', u'name': u'alice'}, u'Music')) => {
    37.     "changed": false,
    38.     "item": [
    39.         {
    40.             "gender": "female",
    41.             "name": "alice"
    42.         },
    43.         "Music"
    44.     ],
    45.     "msg": [
    46.         {
    47.             "gender": "female",
    48.             "name": "alice"
    49.         },
    50.         "Music"
    51.     ]
    52. }
    复制代码
    从上述输出信息可以看出,一共输出了三个item,第一个item中,bob的名字和性别组成了一个小整体,与bob的滑板爱好组合在了一起,第二个item中,bob的名字和性别组成了一个整体,与bob的打电动爱好组合在了一起,第三个item中,alice的名字与性别组成了一个整体,与alice的音乐爱好组合在了一起,你一定看出了一些规律,规律就是,"with_subelements"会将hobby子元素列表中的每一项作为一个整体,将其他子元素作为一个整体,然后组合在一起,所以,我们可以将上例的playbook修改一下,将msg信息的可读性提高一点,示例如下:
    1. ---
    2. - hosts: test70
    3.   remote_user: root
    4.   gather_facts: no
    5.   vars:
    6.     users:
    7.     - name: bob
    8.       gender: male
    9.       hobby:
    10.         - Skateboard
    11.         - VideoGame
    12.     - name: alice
    13.       gender: female
    14.       hobby:
    15.         - Music
    16.   tasks:
    17.   - debug:
    18.       msg: "{{ item.0.name }} 's hobby is {{ item.1 }}"
    19.     with_subelements:
    20.     - "{{users}}"
    21.     - hobby
    复制代码
    由于item由两个整体组成,所以,我们通过item.0获取到第一个小整体,即gender和name属性,然后通过item.1获取到第二个小整体,即hobby列表中的每一项,上例执行后,最终每个msg信息的输出如下:
    1. "msg": "bob 's hobby is Skateboard"
    2. "msg": "bob 's hobby is VideoGame"
    3. "msg": "alice 's hobby is Music"
    复制代码
    经过上述示例,你一定已经明白了"with_subelements"的用法了,"with_subelements"可以处理一个像上例中一样的复合结构的字典数据,在处理这个字典的同时,需要指定一个子元素,这个子元素的值必须是一个列表,之后,"with_subelements"会将子元素的列表中的每一项作为一个整体,将其他子元素作为一个整体,然后将两个整体组合成item。

    "with_dict"和"with_subelements"的用法就先总结到这里,希望这篇文章能够对你有所帮助

    帖子永久地址: 

    黑帽联盟 - 论坛版权1、本主题所有言论和图片纯属会员个人意见,与本论坛立场无关
    2、本站所有主题由该帖子作者发表,该帖子作者与黑帽联盟享有帖子相关版权
    3、其他单位或个人使用、转载或引用本文时必须同时征得该帖子作者和黑帽联盟的同意
    4、帖子作者须承担一切因本文发表而直接或间接导致的民事或刑事法律责任
    5、本帖部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责
    6、如本帖侵犯到任何版权问题,请立即告知本站,本站将及时予与删除并致以最深的歉意
    7、黑帽联盟管理员和版主有权不事先通知发贴者而删除本文

    您需要登录后才可以回帖 登录 | 会员注册

    发布主题 !fastreply! 收藏帖子 返回列表 搜索
    回顶部