当前位置: 首页 > news >正文

台山网站开发seo外链怎么做能看到效果

台山网站开发,seo外链怎么做能看到效果,b2b公司,ui手机app界面设计环境 管理节点&#xff1a;Ubuntu 22.04控制节点&#xff1a;CentOS 8Ansible&#xff1a;2.15.6 循环的方法 loopwith_<lookup>until 用这几种方式都可以实现循环。其中&#xff0c; loop 是推荐的用法&#xff0c;在很多时候能够替换 with_<lookup> 。 loop…

环境

  • 管理节点:Ubuntu 22.04
  • 控制节点:CentOS 8
  • Ansible:2.15.6

循环的方法

  • loop
  • with_<lookup>
  • until

用这几种方式都可以实现循环。其中, loop 是推荐的用法,在很多时候能够替换 with_<lookup>

loopwith_<lookup>

with_<lookup> 使用了lookup插件,比如 with_items 使用的是 items lookup。(注:可参见我另一篇文档。)

loop 等同于 with_list 。注意, loop 是作用在list上的,如果用在字符串上会报错。

---
- hosts: alltasks:- name: task1debug:msg: "{{ item }}"loop: "{{ ['aaa', 'bbb', 'ccc'] }}"- name: task2debug:msg: "{{ item }}"with_list: "{{ ['aaa', 'bbb', 'ccc'] }}"- name: task3debug:msg: "{{ item }}"with_items: "{{ ['aaa', 'bbb', 'ccc'] }}"

运行结果如下:

TASK [task1] ***************************************************************************************
ok: [192.168.1.55] => (item=aaa) => {"msg": "aaa"
}
ok: [192.168.1.55] => (item=bbb) => {"msg": "bbb"
}
ok: [192.168.1.55] => (item=ccc) => {"msg": "ccc"
}TASK [task2] ***************************************************************************************
ok: [192.168.1.55] => (item=aaa) => {"msg": "aaa"
}
ok: [192.168.1.55] => (item=bbb) => {"msg": "bbb"
}
ok: [192.168.1.55] => (item=ccc) => {"msg": "ccc"
}TASK [task3] ***************************************************************************************
ok: [192.168.1.55] => (item=aaa) => {"msg": "aaa"
}
ok: [192.168.1.55] => (item=bbb) => {"msg": "bbb"
}
ok: [192.168.1.55] => (item=ccc) => {"msg": "ccc"
}

可见,本例中 loopwith_listwith_items 的效果是一样的。

但是对于嵌套的list, loopwith_items 并不是完全等同的。

......- name: task4debug:msg: "{{ item }}"loop: "{{ ['aaa', ['bbb', ['ddd', 'eee']], 'ccc'] }}"- name: task5debug:msg: "{{ item }}"with_items: "{{ ['aaa', ['bbb', ['ddd', 'eee']], 'ccc'] }}"
......

运行结果如下:

TASK [task4] ***************************************************************************************
ok: [192.168.1.55] => (item=aaa) => {"msg": "aaa"
}
ok: [192.168.1.55] => (item=['bbb', ['ddd', 'eee']]) => {"msg": ["bbb",["ddd","eee"]]
}
ok: [192.168.1.55] => (item=ccc) => {"msg": "ccc"
}TASK [task5] ***************************************************************************************
ok: [192.168.1.55] => (item=aaa) => {"msg": "aaa"
}
ok: [192.168.1.55] => (item=bbb) => {"msg": "bbb"
}
ok: [192.168.1.55] => (item=['ddd', 'eee']) => {"msg": ["ddd","eee"]
}
ok: [192.168.1.55] => (item=ccc) => {"msg": "ccc"
}

可见:

  • loop 只针对最外层的list,不管是否有嵌套。
  • with_items 则是解开了第一层嵌套的list。这个行为比较诡异,要么就不要管嵌套,要么就全部处理,为什么只处理第一层嵌套呢?

实际上,对于 loop ,可用 flatten filter来指定解开嵌套:

(注:flatten是扁平化的意思,这里的扁平化和Java8里扁平化流的概念类似,即把层次结构转换为线性结构)

......- name: task6debug:msg: "{{ item }}"loop: "{{ ['aaa', ['bbb', ['ddd', 'eee']], 'ccc'] | flatten }}"- name: task7debug:msg: "{{ item }}"loop: "{{ ['aaa', ['bbb', ['ddd', 'eee']], 'ccc'] | flatten(levels=1) }}"
......

运行结果如下:

TASK [task6] ***************************************************************************************
ok: [192.168.1.55] => (item=aaa) => {"msg": "aaa"
}
ok: [192.168.1.55] => (item=bbb) => {"msg": "bbb"
}
ok: [192.168.1.55] => (item=ddd) => {"msg": "ddd"
}
ok: [192.168.1.55] => (item=eee) => {"msg": "eee"
}
ok: [192.168.1.55] => (item=ccc) => {"msg": "ccc"
}TASK [task7] ***************************************************************************************
ok: [192.168.1.55] => (item=aaa) => {"msg": "aaa"
}
ok: [192.168.1.55] => (item=bbb) => {"msg": "bbb"
}
ok: [192.168.1.55] => (item=['ddd', 'eee']) => {"msg": ["ddd","eee"]
}
ok: [192.168.1.55] => (item=ccc) => {"msg": "ccc"
}

可见, flatten 默认会处理所有嵌套,也可以通过 levels 选项,指定处理几层嵌套。

由于 with_items 处理一层嵌套,所以, with_items 就相当于 loop 指定了 flatten(levels=1) 。在本例中,task5和task7的运行结果是一样的。

需要使用 lookup 的循环,多使用 with_<lookup> 语句,而不是 loop 语句。比如:

---
- hosts: alltasks:- name: task1debug:msg: "{{ item }}"loop: "{{ lookup('fileglob', '/tmp/*.txt', wantlist=True) }}"- name: task2debug:msg: "{{ item }}"with_fileglob: "/tmp/*.txt"

运行结果如下:

TASK [task1] ***************************************************************************************
ok: [192.168.1.55] => (item=/tmp/b.txt) => {"msg": "/tmp/b.txt"
}
ok: [192.168.1.55] => (item=/tmp/a.txt) => {"msg": "/tmp/a.txt"
}TASK [task2] ***************************************************************************************
ok: [192.168.1.55] => (item=/tmp/b.txt) => {"msg": "/tmp/b.txt"
}
ok: [192.168.1.55] => (item=/tmp/a.txt) => {"msg": "/tmp/a.txt"
}

显然,此处使用 with_fileglob 比使用 loop 要简洁。

注: fileglob 获取指定目录下符合条件的文件名(不包含子目录)。

循环的种类

简单list

---
- hosts: allvars:var1: ['aaa', 'bbb', 'ccc']tasks:- name: task1 # list常量debug:msg: "{{ item }}"loop: "{{ ['aaa', 'bbb', 'ccc'] }}"# loop: ['aaa', 'bbb', 'ccc'] 可以简写- name: task2 # list常量debug:msg: "{{ item }}"loop:- aaa # 引号可以省略- "bbb"- "ccc"- name: task3 # list变量debug:msg: "{{ item }}"loop: "{{ var1 }}"

运行结果如下:

TASK [task1] ***************************************************************************************
ok: [192.168.1.55] => (item=aaa) => {"msg": "aaa"
}
ok: [192.168.1.55] => (item=bbb) => {"msg": "bbb"
}
ok: [192.168.1.55] => (item=ccc) => {"msg": "ccc"
}TASK [task2] ***************************************************************************************
ok: [192.168.1.55] => (item=aaa) => {"msg": "aaa"
}
ok: [192.168.1.55] => (item=bbb) => {"msg": "bbb"
}
ok: [192.168.1.55] => (item=ccc) => {"msg": "ccc"
}TASK [task3] ***************************************************************************************
ok: [192.168.1.55] => (item=aaa) => {"msg": "aaa"
}
ok: [192.168.1.55] => (item=bbb) => {"msg": "bbb"
}
ok: [192.168.1.55] => (item=ccc) => {"msg": "ccc"
}

复杂list

---
- hosts: allvars:var1: [{name: "Tom", age: 20}, {name: "Jerry", age: 18}]tasks:- name: task1debug:msg: "Name: {{ item.name }}. Age: {{ item.age }}"loop: "{{ [{ 'name': 'Tom', 'age': 20 }, { 'name': 'Jerry', 'age': 18 }] }}"#loop: "{{ [{ name: 'Tom', age: 20 }, { name: 'Jerry', age: 18 }] }}" # 报错!说name未定义#loop: [{ name: 'Tom', age: 20 }, { name: 'Jerry', age: 18 }] # OK#loop: [{ 'name': 'Tom', 'age': 20 }, { 'name': 'Jerry', 'age': 18 }] # OK- name: task2debug:msg: "Name: {{ item.name }}. Age: {{ item.age }}"loop:- { name: "Tom", age: 20 }- { name: "Jerry", age: 18 }- name: task3debug:msg: "Name: {{ item.name }}. Age: {{ item.age }}"loop: "{{ var1 }}"

可以看到,对于key要不要加引号,行为好像有点诡异,最好还是加上吧。

运行结果如下:

TASK [task1] ***************************************************************************************
ok: [192.168.1.55] => (item={'name': 'Tom', 'age': 20}) => {"msg": "Name: Tom. Age: 20"
}
ok: [192.168.1.55] => (item={'name': 'Jerry', 'age': 18}) => {"msg": "Name: Jerry. Age: 18"
}TASK [task2] ***************************************************************************************
ok: [192.168.1.55] => (item={'name': 'Tom', 'age': 20}) => {"msg": "Name: Tom. Age: 20"
}
ok: [192.168.1.55] => (item={'name': 'Jerry', 'age': 18}) => {"msg": "Name: Jerry. Age: 18"
}TASK [task3] ***************************************************************************************
ok: [192.168.1.55] => (item={'name': 'Tom', 'age': 20}) => {"msg": "Name: Tom. Age: 20"
}
ok: [192.168.1.55] => (item={'name': 'Jerry', 'age': 18}) => {"msg": "Name: Jerry. Age: 18"
}

dict

如果要遍历一个dict,则需要使用 dict2items filter,将其转换为list:

---
- hosts: allvars:var1: {name: "Tom", age: 20}tasks:- name: task1debug:msg: "Key: {{ item.key }}. Value: {{ item.value }}"loop: "{{ {'name': 'Tom', 'age': 20} | dict2items }}"- name: task2debug:msg: "Key: {{ item.key }}. Value: {{ item.value }}"loop: "{{ var1 | dict2items }}"

运行结果如下:

TASK [task1] ***************************************************************************************
ok: [192.168.1.55] => (item={'key': 'name', 'value': 'Tom'}) => {"msg": "Key: name. Value: Tom"
}
ok: [192.168.1.55] => (item={'key': 'age', 'value': 20}) => {"msg": "Key: age. Value: 20"
}TASK [task2] ***************************************************************************************
ok: [192.168.1.55] => (item={'key': 'name', 'value': 'Tom'}) => {"msg": "Key: name. Value: Tom"
}
ok: [192.168.1.55] => (item={'key': 'age', 'value': 20}) => {"msg": "Key: age. Value: 20"
}

本例中,dict为:

{name: "Tom", age: 20}

转为list后:

    [{"key": "name","value": "Tom"},{"key": "age","value": 20}]

循环结果的register变量

---
- hosts: alltasks:- name: task1shell: "echo {{ item }}"loop: "{{ ['aaa', 'bbb'] }}"register: var1- name: task2debug:msg: "{{ var1 }}"

运行结果如下:

TASK [task1] ***************************************************************************************
changed: [192.168.1.55] => (item=aaa)
changed: [192.168.1.55] => (item=bbb)TASK [task2] ***************************************************************************************
ok: [192.168.1.55] => {"msg": {"changed": true,"msg": "All items completed","results": [{"ansible_loop_var": "item","changed": true,"cmd": "echo aaa","delta": "0:00:00.002332","end": "2023-11-21 22:29:54.990234","failed": false,"invocation": {"module_args": {"_raw_params": "echo aaa","_uses_shell": true,"argv": null,"chdir": null,"creates": null,"executable": null,"removes": null,"stdin": null,"stdin_add_newline": true,"strip_empty_ends": true}},"item": "aaa","msg": "","rc": 0,"start": "2023-11-21 22:29:54.987902","stderr": "","stderr_lines": [],"stdout": "aaa","stdout_lines": ["aaa"]},{"ansible_loop_var": "item","changed": true,"cmd": "echo bbb","delta": "0:00:00.002036","end": "2023-11-21 22:29:55.223227","failed": false,"invocation": {"module_args": {"_raw_params": "echo bbb","_uses_shell": true,"argv": null,"chdir": null,"creates": null,"executable": null,"removes": null,"stdin": null,"stdin_add_newline": true,"strip_empty_ends": true}},"item": "bbb","msg": "","rc": 0,"start": "2023-11-21 22:29:55.221191","stderr": "","stderr_lines": [],"stdout": "bbb","stdout_lines": ["bbb"]}],"skipped": false}
}

可见,register变量把循环操作的结果放到了叫做 results 的list里。因此,后续可以遍历 results ,做相应处理,比如:

---
- hosts: alltasks:- name: task1shell: "cat {{ item }}"loop: "{{ ['/tmp/a.txt', '/tmp/d.txt'] }}"register: var1ignore_errors: true- name: task2debug:msg: "{{ var1 }}"- name: task3fail:msg: "Something is wrong!"when: item.rc != 0loop: "{{ var1.results }}"

假设 /tmp/d.txt 不存在,则运行结果如下:

TASK [task1] ***************************************************************************************
changed: [192.168.1.55] => (item=/tmp/a.txt)
failed: [192.168.1.55] (item=/tmp/d.txt) => {"ansible_loop_var": "item", "changed": true, "cmd": "cat /tmp/d.txt", "delta": "0:00:00.002438", "end": "2023-11-21 22:46:28.216904", "item": "/tmp/d.txt", "msg": "non-zero return code", "rc": 1, "start": "2023-11-21 22:46:28.214466", "stderr": "cat: /tmp/d.txt: No such file or directory", "stderr_lines": ["cat: /tmp/d.txt: No such file or directory"], "stdout": "", "stdout_lines": []}
...ignoringTASK [task2] ***************************************************************************************
ok: [192.168.1.55] => {"msg": {"changed": true,"failed": true,"msg": "One or more items failed","results": [{"ansible_loop_var": "item","changed": true,"cmd": "cat /tmp/a.txt","delta": "0:00:00.003006","end": "2023-11-21 22:46:27.995302","failed": false,"invocation": {"module_args": {"_raw_params": "cat /tmp/a.txt","_uses_shell": true,"argv": null,"chdir": null,"creates": null,"executable": null,"removes": null,"stdin": null,"stdin_add_newline": true,"strip_empty_ends": true}},"item": "/tmp/a.txt","msg": "","rc": 0,"start": "2023-11-21 22:46:27.992296","stderr": "","stderr_lines": [],"stdout": "aaaaa\nb\nccccc","stdout_lines": ["aaaaa","b","ccccc"]},{"ansible_loop_var": "item","changed": true,"cmd": "cat /tmp/d.txt","delta": "0:00:00.002438","end": "2023-11-21 22:46:28.216904","failed": true,"invocation": {"module_args": {"_raw_params": "cat /tmp/d.txt","_uses_shell": true,"argv": null,"chdir": null,"creates": null,"executable": null,"removes": null,"stdin": null,"stdin_add_newline": true,"strip_empty_ends": true}},"item": "/tmp/d.txt","msg": "non-zero return code","rc": 1,"start": "2023-11-21 22:46:28.214466","stderr": "cat: /tmp/d.txt: No such file or directory","stderr_lines": ["cat: /tmp/d.txt: No such file or directory"],"stdout": "","stdout_lines": []}],"skipped": false}
}TASK [task3] ***************************************************************************************
skipping: [192.168.1.55] => (item={'changed': True, 'stdout': 'aaaaa\nb\nccccc', 'stderr': '', 'rc': 0, 'cmd': 'cat /tmp/a.txt', 'start': '2023-11-21 22:46:27.992296', 'end': '2023-11-21 22:46:27.995302', 'delta': '0:00:00.003006', 'msg': '', 'invocation': {'module_args': {'_raw_params': 'cat /tmp/a.txt', '_uses_shell': True, 'stdin_add_newline': True, 'strip_empty_ends': True, 'argv': None, 'chdir': None, 'executable': None, 'creates': None, 'removes': None, 'stdin': None}}, 'stdout_lines': ['aaaaa', 'b', 'ccccc'], 'stderr_lines': [], 'failed': False, 'item': '/tmp/a.txt', 'ansible_loop_var': 'item'}) 
failed: [192.168.1.55] (item={'changed': True, 'stdout': '', 'stderr': 'cat: /tmp/d.txt: No such file or directory', 'rc': 1, 'cmd': 'cat /tmp/d.txt', 'start': '2023-11-21 22:46:28.214466', 'end': '2023-11-21 22:46:28.216904', 'delta': '0:00:00.002438', 'failed': True, 'msg': 'non-zero return code', 'invocation': {'module_args': {'_raw_params': 'cat /tmp/d.txt', '_uses_shell': True, 'stdin_add_newline': True, 'strip_empty_ends': True, 'argv': None, 'chdir': None, 'executable': None, 'creates': None, 'removes': None, 'stdin': None}}, 'stdout_lines': [], 'stderr_lines': ['cat: /tmp/d.txt: No such file or directory'], 'item': '/tmp/d.txt', 'ansible_loop_var': 'item'}) => {"ansible_loop_var": "item", "changed": false, "item": {"ansible_loop_var": "item", "changed": true, "cmd": "cat /tmp/d.txt", "delta": "0:00:00.002438", "end": "2023-11-21 22:46:28.216904", "failed": true, "invocation": {"module_args": {"_raw_params": "cat /tmp/d.txt", "_uses_shell": true, "argv": null, "chdir": null, "creates": null, "executable": null, "removes": null, "stdin": null, "stdin_add_newline": true, "strip_empty_ends": true}}, "item": "/tmp/d.txt", "msg": "non-zero return code", "rc": 1, "start": "2023-11-21 22:46:28.214466", "stderr": "cat: /tmp/d.txt: No such file or directory", "stderr_lines": ["cat: /tmp/d.txt: No such file or directory"], "stdout": "", "stdout_lines": []}, "msg": "Something is wrong!"}

本例中,由于 /tmp/d.txt 不存在, results 的第2个元素,其rc值为1。

注意:每一次迭代,其结果就会放到register变量里,而不是整个循环结束后才放的。

---
- hosts: alltasks:- name: task1shell: echo "{{ item }}"loop:- "aaa"- "bbb"register: var1changed_when: var1.stdout != "aaa"

运行结果如下:

TASK [task1] ***************************************************************************************
ok: [192.168.1.55] => (item=aaa)
changed: [192.168.1.55] => (item=bbb)

可见,第一次迭代没有满足判断条件,而第二次迭代满足判断条件了。

复杂循环

遍历嵌套list

---
- hosts: alltasks:- name: task1debug:msg: "{{ item[0] }} {{ item[1] }}"loop: "{{ ['Zhang', 'Li'] | product(['San', 'Si']) | list }}"

运行结果如下:

TASK [task1] ***************************************************************************************
ok: [192.168.1.55] => (item=['Zhang', 'San']) => {"msg": "Zhang San"
}
ok: [192.168.1.55] => (item=['Zhang', 'Si']) => {"msg": "Zhang Si"
}
ok: [192.168.1.55] => (item=['Li', 'San']) => {"msg": "Li San"
}
ok: [192.168.1.55] => (item=['Li', 'Si']) => {"msg": "Li Si"
}

本例中,把两个list做笛卡尔乘积,生成了一个新的嵌套list:

    [["Zhang","San"],["Zhang","Si"],["Li","San"],["Li","Si"]]

然后遍历外层list,并通过 item[0]item[1] 访问内层list的元素。

Retry

---
- hosts: alltasks:- name: task1shell: cat /tmp/a.txtregister: var1until: var1.stdout.find("OK") != -1retries: 3delay: 5

运行结果如下:

TASK [task1] ***************************************************************************************
FAILED - RETRYING: [192.168.1.55]: task1 (3 retries left).
FAILED - RETRYING: [192.168.1.55]: task1 (2 retries left).
FAILED - RETRYING: [192.168.1.55]: task1 (1 retries left).
fatal: [192.168.1.55]: FAILED! => {"attempts": 3, "changed": true, "cmd": "cat /tmp/a.txt", "delta": "0:00:00.002228", "end": "2023-11-23 07:53:18.333193", "msg": "", "rc": 0, "start": "2023-11-23 07:53:18.330965", "stderr": "", "stderr_lines": [], "stdout": "aaaaa\nb\nccccc", "stdout_lines": ["aaaaa", "b", "ccccc"]}

在运行过程中,编辑 /tmp/a.txt 文件(注意是在目标机器上),添加 OK 的内容,则运行结果如下:

TASK [task1] ***************************************************************************************
FAILED - RETRYING: [192.168.1.55]: task1 (3 retries left).
FAILED - RETRYING: [192.168.1.55]: task1 (2 retries left).
changed: [192.168.1.55]

注:

  • retries 的缺省值是 3delay 的缺省值是 5

遍历inventory

假设 /etc/ansible/hosts 内容如下:

[myvms]
192.168.1.55[myself]
127.0.0.1
---
- hosts: alltasks:- name: task1debug:msg: "{{ item }}"loop: "{{ groups['all'] }}"#loop: "{{ groups['myvms'] }}"

运行结果如下:

TASK [task1] ***************************************************************************************
ok: [192.168.1.55] => (item=192.168.1.55) => {"msg": "192.168.1.55"
}
ok: [192.168.1.55] => (item=127.0.0.1) => {"msg": "127.0.0.1"
}
ok: [127.0.0.1] => (item=192.168.1.55) => {"msg": "192.168.1.55"
}
ok: [127.0.0.1] => (item=127.0.0.1) => {"msg": "127.0.0.1"
}

可见,打印了所有的主机名。

为什么打印了两次呢?这是因为指定了 hosts: all ,所以在两个目标机器上都运行了一次。

若改为 hosts: myvms ,则运行结果如下:

TASK [task1] ***************************************************************************************
ok: [192.168.1.55] => (item=192.168.1.55) => {"msg": "192.168.1.55"
}
ok: [192.168.1.55] => (item=127.0.0.1) => {"msg": "127.0.0.1"
}

如果只想遍历 myvms ,则把 loop: "{{ groups['all'] }}" 改为 loop: "{{ groups['myvms'] }}" ,运行结果如下:

TASK [task1] ***************************************************************************************
ok: [192.168.1.55] => (item=192.168.1.55) => {"msg": "192.168.1.55"
}

也可以通过 loop: "{{ ansible_play_batch }}" 指定遍历当前play的主机:

TASK [task1] ***************************************************************************************
ok: [192.168.1.55] => (item=192.168.1.55) => {"msg": "192.168.1.55"
}

注: groupsansible_play_batch 都是Ansible的特殊变量,参见 https://docs.ansible.com/ansible/latest/reference_appendices/special_variables.html

还可以通过 inventory_hostnames lookup来指定遍历的主机:

---
- hosts: myvmstasks:- name: task1debug:msg: "{{ item }}"loop: "{{ query('inventory_hostnames', 'all') }}"

运行结果如下:

TASK [task1] ***************************************************************************************
ok: [192.168.1.55] => (item=192.168.1.55) => {"msg": "192.168.1.55"
}
ok: [192.168.1.55] => (item=127.0.0.1) => {"msg": "127.0.0.1"
}

遍历 all ,同时排除 myvms ,则指定:loop: "{{ query('inventory_hostnames', 'all:!myvms') }}"

TASK [task1] ***************************************************************************************
ok: [192.168.1.55] => (item=127.0.0.1) => {"msg": "127.0.0.1"
}

loop_control

label

前面我们提到,遍历一个dict:

---
- hosts: allvars:var1: {name: "Tom", age: 20}tasks:- name: task1debug:msg: "Key: {{ item.key }}. Value: {{ item.value }}"loop: "{{ {'name': 'Tom', 'age': 20} | dict2items }}"#loop_control:#  label: "{{ item.key}}"

运行结果如下:

TASK [task1] ***************************************************************************************
ok: [192.168.1.55] => (item={'key': 'name', 'value': 'Tom'}) => {"msg": "Key: name. Value: Tom"
}
ok: [192.168.1.55] => (item={'key': 'age', 'value': 20}) => {"msg": "Key: age. Value: 20"
}

注意其中的 (item={'key': 'name', 'value': 'Tom'}) 等,如果item数据量很大,则输出量很大。此处可以使用 label 指定打印的内容(比如只打印key,不打印value),见注释部分。

运行结果如下:

TASK [task1] ***************************************************************************************
ok: [192.168.1.55] => (item=name) => {"msg": "Key: name. Value: Tom"
}
ok: [192.168.1.55] => (item=age) => {"msg": "Key: age. Value: 20"
}

pause

在每次循环迭代之间,暂停一段时间(秒)。

---
- hosts: alltasks:- name: task1debug:msg: "{{ item }}"loop: "{{ ['aaa', 'bbb', 'ccc'] }}"loop_control:pause: 3

index_var

指定下标变量,然后通过该变量获取下标值(从0开始)。

---
- hosts: alltasks:- name: task1debug:msg: "{{ idx }}: {{ item }}"loop: "{{ ['aaa', 'bbb', 'ccc'] }}"loop_control:index_var: idx

运行结果如下:

TASK [task1] ***************************************************************************************
ok: [192.168.1.55] => (item=aaa) => {"msg": "0: aaa"
}
ok: [192.168.1.55] => (item=bbb) => {"msg": "1: bbb"
}
ok: [192.168.1.55] => (item=ccc) => {"msg": "2: ccc"
}

loop_var

循环的元素名称,默认叫做 item ,而对于嵌套循环,为避免混淆内外循环的item,可用 loop_var 指定item名称。

创建文件 test19.yml 如下:

---
- hosts: alltasks:- name: task1include_tasks: test20.ymlloop: [1, 2, 3]loop_control:loop_var: item_outer

创建文件 test20.yml 如下:

---
- name: inner_task1debug:msg: "Outer item = {{ item_outer }}, Inner item = {{ item_inner }}"loop: "{{ ['aaa', 'bbb', 'ccc'] }}"loop_control:loop_var: item_inner

运行结果如下:

TASK [task1] ***************************************************************************************
included: /root/temp/temp1121/test20.yml for 192.168.1.55 => (item=1)
included: /root/temp/temp1121/test20.yml for 192.168.1.55 => (item=2)
included: /root/temp/temp1121/test20.yml for 192.168.1.55 => (item=3)TASK [inner_task1] *********************************************************************************
ok: [192.168.1.55] => (item=aaa) => {"msg": "Outer item = 1, Inner item = aaa"
}
ok: [192.168.1.55] => (item=bbb) => {"msg": "Outer item = 1, Inner item = bbb"
}
ok: [192.168.1.55] => (item=ccc) => {"msg": "Outer item = 1, Inner item = ccc"
}TASK [inner_task1] *********************************************************************************
ok: [192.168.1.55] => (item=aaa) => {"msg": "Outer item = 2, Inner item = aaa"
}
ok: [192.168.1.55] => (item=bbb) => {"msg": "Outer item = 2, Inner item = bbb"
}
ok: [192.168.1.55] => (item=ccc) => {"msg": "Outer item = 2, Inner item = ccc"
}TASK [inner_task1] *********************************************************************************
ok: [192.168.1.55] => (item=aaa) => {"msg": "Outer item = 3, Inner item = aaa"
}
ok: [192.168.1.55] => (item=bbb) => {"msg": "Outer item = 3, Inner item = bbb"
}
ok: [192.168.1.55] => (item=ccc) => {"msg": "Outer item = 3, Inner item = ccc"
}

本例中,外部循环的item命名为 item_outer ,而内部循环的item命名为 item_inner

扩展循环变量

添加 extended: true ,则可以访问如下变量:

  • ansible_loop.allitems :所有元素
  • ansible_loop.index :从1开始
  • ansible_loop.index0 :从0开始
  • ansible_loop.revindex :倒数,从1开始
  • ansible_loop.revindex0 :倒数,从0开始
  • ansible_loop.first :是否是第一个元素
  • ansible_loop.last :是否是最后一个元素
  • ansible_loop.length :元素数量
  • ansible_loop.previtem :前一个元素(第一次迭代时未定义)
  • ansible_loop.nextitem :后一个元素(最后一次迭代时未定义)
---
- hosts: alltasks:- name: task1debug:msg: "ansible_loop.allitems = {{ ansible_loop.allitems }}, ansible_loop.index = {{ ansible_loop.index }}, ansible_loop.index0 = {{ ansible_loop.index0 }}, ansible_loop.revindex = {{ ansible_loop.revindex }}, ansible_loop.revindex0 = {{ ansible_loop.revindex0 }}, ansible_loop.first = {{ ansible_loop.first }}, ansible_loop.last = {{ ansible_loop.last }}, ansible_loop.length = {{ ansible_loop.length }}, ansible_loop.previtem = {{ ansible_loop.previtem | default('no previous') }}, ansible_loop.nextitem = {{ ansible_loop.nextitem | default('no next') }}"loop: "{{ ['aaa', 'bbb', 'ccc'] }}"loop_control:extended: true

运行结果如下:

TASK [task1] ***************************************************************************************
ok: [192.168.1.55] => (item=aaa) => {"msg": "ansible_loop.allitems = ['aaa', 'bbb', 'ccc'], ansible_loop.index = 1, ansible_loop.index0 = 0, ansible_loop.revindex = 3, ansible_loop.revindex0 = 2, ansible_loop.first = True, ansible_loop.last = False, ansible_loop.length = 3, ansible_loop.previtem = no previous, ansible_loop.nextitem = bbb"
}
ok: [192.168.1.55] => (item=bbb) => {"msg": "ansible_loop.allitems = ['aaa', 'bbb', 'ccc'], ansible_loop.index = 2, ansible_loop.index0 = 1, ansible_loop.revindex = 2, ansible_loop.revindex0 = 1, ansible_loop.first = False, ansible_loop.last = False, ansible_loop.length = 3, ansible_loop.previtem = aaa, ansible_loop.nextitem = ccc"
}
ok: [192.168.1.55] => (item=ccc) => {"msg": "ansible_loop.allitems = ['aaa', 'bbb', 'ccc'], ansible_loop.index = 3, ansible_loop.index0 = 2, ansible_loop.revindex = 1, ansible_loop.revindex0 = 0, ansible_loop.first = False, ansible_loop.last = True, ansible_loop.length = 3, ansible_loop.previtem = bbb, ansible_loop.nextitem = no next"
}

注:如果 ansible_loop.allitems 很大,为了节省内存,可以设置 extended_allitems: false

loop_control:extended: trueextended_allitems: false

获取 loop_var 的值

比如指定了 loop_var: myitem ,则可以通过 {{ myitem }} 来获取item,也可以通过 {{ lookup('vars', ansible_loop_var) }} 获取item。

---
- hosts: alltasks:- name: task1debug:msg: "{{ myitem }} , {{ lookup('vars', ansible_loop_var) }}"loop: [1, 2, 3]loop_control:loop_var: myitem

运行结果如下:

TASK [task1] ***************************************************************************************
ok: [192.168.1.55] => (item=1) => {"msg": "1 , 1"
}
ok: [192.168.1.55] => (item=2) => {"msg": "2 , 2"
}
ok: [192.168.1.55] => (item=3) => {"msg": "3 , 3"
}

可见,二者效果是一样的。

参考

  • https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_loops.html
  • https://docs.ansible.com/ansible/latest/reference_appendices/special_variables.html
  • https://docs.ansible.com/ansible/latest/inventory_guide/intro_patterns.html
http://www.khdw.cn/news/33225.html

相关文章:

  • 中国品牌100强排名重庆的seo服务公司
  • 网站架设百度关键词排名突然消失了
  • 某购物网站开发项目唐山seo快速排名
  • 高考写作网站网站建设优化
  • 单页营销网站设计微信scrm系统
  • 无锡做网站需要多少钱天津网络广告公司
  • seo网站系统网站怎么做推广
  • 网页制作与网站建设实战大全pdf大金seo
  • 网站建设冷色调友情链接的形式有哪些
  • 学校网站模板 中文版外贸seo是什么意思
  • 深圳响应样式网站建设费用中央广播电视总台
  • 谷歌网站推广方案100个关键词
  • 互动平台论坛手机优化软件
  • 梧州网站建设电话商丘seo外包
  • 重庆哪家网站今日足球最新预测比分
  • 苏州建站模板厂家百度ocpc如何优化
  • 做破解的网站手机百度高级搜索
  • 网站建设培训教程社交媒体营销策略有哪些
  • 宜兴网站建设创意营销点子
  • 怎么做关于易烊千玺的网站网络推广免费网站
  • 教育培训网站有哪些条友网
  • 做网站设计的提成点是多少常见搜索引擎有哪些
  • 做海报的高清模板的网站百度怎么做推广
  • 做爰片的网站什么是域名
  • 自己的公司怎么做网站营销方式都有哪些
  • 二手设备回收做哪个网站好爱站关键词挖掘old
  • 做的网站老是掉线seo关键词快速排名
  • 找网站做网站做网站南通seo网站优化软件
  • 朝阳网站建设 慈云寺怎么创建网站快捷方式
  • 做网站彩票代理多少钱啊电商是做什么的