黑帽联盟

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

[基础服务] ansible笔记(21):循环(三)

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

920

主题

37

听众

1364

积分

超级版主

Rank: 8Rank: 8

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

    [LV.9]以坛为家II

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

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


    前文中我们已经了解了一些用于循环的关键字,比如 with_list、with_items、with_flattened、with_together,这篇文章我们继续。

    假设,现在我有一个需求,我需要在目标主机的测试目录中创建a、b、c三个目录,这三个目录都有相同的子目录,它们都有test1和test2两个子目录,使用最原始的办法,我们可以在目标主机上执行如下一堆命令
    1. # pwd
    2. /testdir/testdir
    3. # mkdir -p a/test1
    4. # mkdir -p a/test2
    5. # mkdir -p b/test1
    6. # mkdir -p b/test2
    7. # mkdir -p c/test1
    8. # mkdir -p c/test2
    复制代码
    当然,我们也可以使用稍微讨巧一点的方法,执行如下命令
    1. # mkdir -p {a,b,c}/{test1,test2}
    复制代码
    如果我们想要使用ansible完成上述需求,我们该怎么做呢?我们能够使用shell模块执行上述命令吗?我们来试试,在ansible主机上执行如下命令
    1. # ansible test70 -m shell -a "mkdir -p /testdir/testdir/{a,b,c}/{test1,test2}"
    复制代码
    我们使用上述命令成功的在目标主机上创建了符合我们要求的目录结构,其实,我们还能够使用循环完成上述工作,如果想要使用循环来完成上述工作,则需要先了解一个用于循环的关键字,这个关键字就是"with_cartesian",这个关键字怎么使用呢?有怎样的效果的呢?来看一个小示例playbook,如下
    1. ---
    2. - hosts: test70
    3.   remote_user: root
    4.   gather_facts: no
    5.   tasks:
    6.   - debug:
    7.       msg: "{{ item }}"
    8.     with_cartesian:
    9.     - [ a, b, c ]
    10.     - [ test1, test2 ]
    复制代码
    上例中定义了一个嵌套的列表,其中嵌套了两个小列表,第一个小列表中有a、b、c三个元素,第二个小列表中有test1、test2两个元素,然后我们使用 with_cartesian关键字处理这个嵌套的列表,然后循环调用debug模块输出了item的值,执行上例playbook后,debug模块的输出信息如下
    1. TASK [debug] ***********************************
    2. ok: [test70] => (item=[u'a', u'test1']) => {
    3.     "changed": false,
    4.     "item": [
    5.         "a",
    6.         "test1"
    7.     ],
    8.     "msg": [
    9.         "a",
    10.         "test1"
    11.     ]
    12. }
    13. ok: [test70] => (item=[u'a', u'test2']) => {
    14.     "changed": false,
    15.     "item": [
    16.         "a",
    17.         "test2"
    18.     ],
    19.     "msg": [
    20.         "a",
    21.         "test2"
    22.     ]
    23. }
    24. ok: [test70] => (item=[u'b', u'test1']) => {
    25.     "changed": false,
    26.     "item": [
    27.         "b",
    28.         "test1"
    29.     ],
    30.     "msg": [
    31.         "b",
    32.         "test1"
    33.     ]
    34. }
    35. ok: [test70] => (item=[u'b', u'test2']) => {
    36.     "changed": false,
    37.     "item": [
    38.         "b",
    39.         "test2"
    40.     ],
    41.     "msg": [
    42.         "b",
    43.         "test2"
    44.     ]
    45. }
    46. ok: [test70] => (item=[u'c', u'test1']) => {
    47.     "changed": false,
    48.     "item": [
    49.         "c",
    50.         "test1"
    51.     ],
    52.     "msg": [
    53.         "c",
    54.         "test1"
    55.     ]
    56. }
    57. ok: [test70] => (item=[u'c', u'test2']) => {
    58.     "changed": false,
    59.     "item": [
    60.         "c",
    61.         "test2"
    62.     ],
    63.     "msg": [
    64.         "c",
    65.         "test2"
    66.     ]
    67. }
    复制代码
    从输出信息可以看出,第一个小列表中的每个元素与第二个小列表中的每个元素都"两两组合在了一起",如下图所示
    1.png

    聪明如你一定看出来了,上图中的排列组合方式就好像笛卡尔乘积中的一样,所以,"with_cartesian"关键字的作用就是将每个小列表中的元素按照"笛卡尔的方式"组合后,循环的处理每个组合,所以,你一定已经想到了,我们可以利用这个特性,完成我们之前创建目录的需求,示例playbook如下:
    1. ---
    2. - hosts: test70
    3.   remote_user: root
    4.   gather_facts: no
    5.   tasks:
    6.   - file:
    7.       state: directory
    8.       path: "/testdir/testdir/{{ item.0 }}/{{ item.1 }}"
    9.     with_cartesian:
    10.     - [ a, b, c ]
    11.     - [ test1, test2 ]
    复制代码
    上例playbook执行后,即可在目标主机中创建出符合我们要求的目录,有了前文中的各种示例作为基础,我想你一定已经看明白了。
    其实,还有一个关键字可以代替"with_cartesian",它就是"with_nested","with_nested"与"with_cartesian"的效果一致,可以无差别使用他们。

    好了,这篇文章就总结到这里,希望对你有所帮助。
    帖子永久地址: 

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

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

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