黑帽联盟

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

[基础服务] ansible笔记(23):循环(五)

[复制链接]
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系列"中的每篇文章都建立在前文的基础之上,所以,请按照顺序阅读这些文章,否则有可能在阅读中遇到障碍。


    现在我有一个需求,我需要使用ansible在目标主机中创建5个目录,这5个目录的名字是test2、test4、test6、test8、test10,我该怎么办呢?当然,我可以使用shell模块执行一条命令去完成,但是我们现在正在总结"循环"的使用方法,所以,我要用循环完成这个需求,使用循环完成这个任务很简单,我们只需要借助一个循环的关键字,它就是"with_sequence",放开刚才的需求不说,我们先来看一个"with_sequence"的小示例,示例playbook如下:
    1. ---
    2. - hosts: test70
    3.   remote_user: root
    4.   gather_facts: no
    5.   tasks:
    6.   - debug:
    7.       msg: "{{ item }}"
    8.     with_sequence: start=1 end=5 stride=1
    复制代码
    我们先不用纠结上例的"with_sequence"设置是什么意思,我们先来看一下上例的执行效果,先执上述playbook后,debug模块的输出结果如下
    1. TASK [debug] ***************************
    2. ok: [test70] => (item=1) => {
    3.     "changed": false,
    4.     "item": "1",
    5.     "msg": "1"
    6. }
    7. ok: [test70] => (item=2) => {
    8.     "changed": false,
    9.     "item": "2",
    10.     "msg": "2"
    11. }
    12. ok: [test70] => (item=3) => {
    13.     "changed": false,
    14.     "item": "3",
    15.     "msg": "3"
    16. }
    17. ok: [test70] => (item=4) => {
    18.     "changed": false,
    19.     "item": "4",
    20.     "msg": "4"
    21. }
    22. ok: [test70] => (item=5) => {
    23.     "changed": false,
    24.     "item": "5",
    25.     "msg": "5"
    26. }
    复制代码
    如输出信息所示,debug模块被循环调用了5次,msg的值从1一直输出到了5,值的大小每次增加1,没错,这正是"with_sequence"关键字的作用,"with_sequence"可以帮助我们按照顺序生成数字序列,上例的playbook中,with_sequence的设置是"start=1 end=5 stride=1",其中start=1表示从1开始,end=5表示到5结束, stride=1表示步长为1,即从1到5每次增加1。
    我们也可以换一种书写格式,如下格式如上例中的格式效果相同
    1.     with_sequence:
    2.       start=1
    3.       end=5
    4.       stride=1
    复制代码
    其实,还有一种更简单的写法,能够生成连续的数字序列,写法如下:
    1. ---
    2. - hosts: test70
    3.   remote_user: root
    4.   gather_facts: no
    5.   tasks:
    6.   - debug:
    7.       msg: "{{item}}"
    8.     with_sequence: count=5
    复制代码
    上例中count=5表示数字序列默认从1开始,到5结束,默认步长为1,与上述两种写法的效果相同。

    当我们不指定stride的值时,stride的值默认为1,但是,当end的值小于start的值时,则必须指定stride的值,而且stride的值必须是负数,示例如下:
    1. ---
    2. - hosts: test70
    3.   remote_user: root
    4.   gather_facts: no
    5.   tasks:
    6.   - debug:
    7.       msg: "{{item}}"
    8.     with_sequence: start=6 end=2 stride=-2
    复制代码
    上例中start的值为6,end的值为2,stride的值为-2,表示从6开始,每次减2,到2结束,上例playbook的执行结果如下:
    1. TASK [debug] ***************************
    2. ok: [test70] => (item=6) => {
    3.     "changed": false,
    4.     "item": "6",
    5.     "msg": "6"
    6. }
    7. ok: [test70] => (item=4) => {
    8.     "changed": false,
    9.     "item": "4",
    10.     "msg": "4"
    11. }
    12. ok: [test70] => (item=2) => {
    13.     "changed": false,
    14.     "item": "2",
    15.     "msg": "2"
    16. }
    复制代码
    看完上述总结,你肯定已经明白了"with_sequence"循环的用法,所以,我们可以使用"with_sequence"完成上述创建目录的需求,示例playbook如下:
    1. ---
    2. - hosts: test70
    3.   remote_user: root
    4.   gather_facts: no
    5.   tasks:
    6.   - file:
    7.       path: "/testdir/testdir/test{{ item }}"
    8.       state: directory
    9.     with_sequence:
    10.       start=2
    11.       end=10
    12.       stride=2
    复制代码
    "with_sequence"还有一个小功能,就是"格式化"输出数据的功能,"格式化数据"的方法与C语言的printf函数的使用方法类似,如果你不了解printf函数,可以参考的文章:printf命令总结,这篇文章介绍了linux下printf命令的用法,虽然C语言的printf与linux的printf命令的使用方法并不完全相同,但是大致类似,还是能够对理解"with_sequence"的格式化功能有所帮助的,此处假设你已经阅读了对应的文章或者已经理解了printf的使用方法,那么我们来看一个格式化数据的小示例,playbook如下:
    1. ---
    2. - hosts: test70
    3.   remote_user: root
    4.   gather_facts: no
    5.   tasks:
    6.   - debug:
    7.       msg: "{{item}}"
    8.     with_sequence: start=2 end=6 stride=2 format="number is %0.2f"
    复制代码
    如上例所示,使用"format"可以指定数据输出的格式,上例中我指定的数据格式为"number is %0.2f",其中,"number is "是我指定的固定字符串," %0.2f"表示将数字格式化为一个保留两位小数点的浮点数,那么上例的playbook执行后debug模块输出信息如下:
    1. TASK [debug] ***************************
    2. ok: [test70] => (item=number is 2.00) => {
    3.     "changed": false,
    4.     "item": "number is 2.00",
    5.     "msg": "number is 2.00"
    6. }
    7. ok: [test70] => (item=number is 4.00) => {
    8.     "changed": false,
    9.     "item": "number is 4.00",
    10.     "msg": "number is 4.00"
    11. }
    12. ok: [test70] => (item=number is 6.00) => {
    13.     "changed": false,
    14.     "item": "number is 6.00",
    15.     "msg": "number is 6.00"
    16. }
    复制代码
    从输出结果可以看出,最终的信息格式与我们所指定的格式完全一致。

    "with_sequence"说完了,再来了解一个新的关键字,它就是"with_random_choice"
    "with_random_choice"的用法非常简单,使用"with_random_choice"可以从列表的多个值中随机返回一个值,先来看一个小示例,playbook如下:
    1. ---
    2. - hosts: test70
    3.   remote_user: root
    4.   gather_facts: no
    5.   tasks:
    6.   - debug:
    7.       msg: "{{item}}"
    8.     with_random_choice:
    9.     - 1
    10.     - 2
    11.     - 3
    12.     - 4
    13.     - 5
    复制代码
    如上例所示,我们定义了一个列表,列表中有5个值,我们使用"with_random_choice"处理这个列表。
    连续执行上例playbook,可以看出每次返回的结果是从列表中随机选中的一个,具体返回结果我就不粘贴了,快动手试试吧~

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

    帖子永久地址: 

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

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

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