{"msg":"操作成功","code":200,"data":{"createBy":"admin","createTime":"2020-08-25 14:16:35","updateBy":"admin","updateTime":"2020-08-25 14:16:35","remark":null,"id":33,"articleTitle":"Ansible（六）Playbook中循环与条件判断","articleUrl":"ansible_flowcontrol","articleThumbnail":"https://www.asumimoe.com/imgfiles/20220908/5969ef61cf754d1aa6e0f5c28219aefa.jpg","articleFlag":"0","draftStatus":"1","reprintStatement":"0","articleSummary":"ansible中的循环都是借助迭代来实现的。基本都是以\"with_\"开头。以下是常见的几种循环......","articleContent":"## 循环\n\n### with_items迭代列表\n\n1. 要安装一些软件包\n\n   ```yml\n   - hosts: localhost\n     tasks:\n       - yum: name=\"{{item}}\" state=installed\n         with_items:\n           - pkg1\n           - pkg2\n           - pkg3\n   ```\n\n   它会一个一个迭代到特殊变量\"{{item}}\"处\n\n2. 指定一些文件列表，然后用grep搜索处给定文件列表中包含\"www.example.com\"字符串的文件。\n\n   ```yml\n   - hosts: localhost\n     tasks:\n       - shell: grep -Rl \"www\\.example\\.com\" \"{{item}}\"\n         with_items:\n           - file1\n           - file2\n           - file3\n         register: match_file\n       - debug: msg=\"{% for i in match_file.results %} {{i.stdout}} {% endfor %}\"\n   ```\n\n   注意，将with_items迭代后的结果注册为变量时，其注册结果也是列表式的，其key为\"results\"。\n   如果不使用上面的for循环，就需要使用数组格式。\n   例如，引用match_file中的第一和第二个结果。\n\n   ```yml\n   - debug: var=match_file.results[0].stdout\n   - debug: var=match_file.results[1].stdout\n   ```\n\n3. 每个列表项中可能含有一个或多个字典，with_items也能迭代列表中的字典。\n\n   ```yml\n   tasks:\n   - command: echo {{ item }}\n     with_items: [ 0, 2, 4, 6, 8, 10 ]\n     register: num\n   - debug: msg=\"{% for i in num.results %} {{i.stdout}} {% endfor %}\"\n   ```\n\n   ```yml\n   - hosts: localhost\n     tasks:\n       - shell: echo \"name={{item.name}},age={{item.age}}\"\n         with_items:\n           - {name: zhangsan,age: 32}\n           - {name: lisi,age: 33}\n           - {name: wangwu,age: 35}\n         register: who\n       - debug: msg=\"{% for i in who.results %} {{i.stdout}} {% endfor %}\"\n   ```\n\n### with_dict迭代字典项\n\n使用with_dict迭代时，使用\"item.key\"表示字典的key，\"item.value\"表示字典的值。\n\n```yml\n- hosts: localhost\n  tasks:\n    - debug: msg=\"{{item.key}} & {{item.value}}\"\n      with_dict: { address: 1,netmask: 2,gateway: 3 }\n```\n\n另一种情况，字典是已经存储好的。例如ansible facts中的ansible_eth0.ipv4，\n\n```yml\n\"ipv4\": {\n\"address\": \"192.168.10.11\",\n\"netmask\": \"255.255.255.0\",\n\"gateway\": \"192.168.10.2\"\n}\n```\n\n这种情况下，with_dict处可以直接指定该字典的key：\n\n```yml\n- hosts: localhost\n  tasks:\n    - debug: msg=\"{{item.key}} & {{item.value}}\"\n      with_dict: ansible_eth0.ipv4\n```\n\n再比如，直接引用playbook中的vars：\n\n```yml\n- hosts: 192.168.100.65\n  gather_facts: False\n  vars:\n    user:\n      longshuai_key:\n        name: longshuai\n        gender: Male\n    xiaofang_key:\n        name: xiaofang\n        gender: Female\n  tasks:\n    - name: print hash loop var\n      debug: msg=\"{{ item.key }} & {{ item.value.name }} & {{ item.value.gender }}\"\n      with_dict: \"{{ user }}\"\n```\n\n### with_fileglob迭代文件\n\n如拷贝用通配符匹配出来的文件到远程主机上。\n\n```yml\n- hosts: centos\n  tasks:\n    - copy: src=\"{{item}}\" dest=/tmp/\n      with_fileglob:\n        - /tmp/*.sh\n        - /tmp/*.py\n```\n\n注意：通配符无法匹配\"/\"，因此无法递归到子目录中，因此无法迭代子目录中的文件。\n\n### with_lines迭代行\n\n可以将命令行的输出结果按行迭代。\n\n```yml\n- hosts: localhost\n  tasks:\n    - copy: src=\"{{item}}\" dest=/tmp/yaml\n      with_lines:\n        - find /tmp -type f -name \"*.yml\"\n```\n\n### with_nested嵌套迭代\n\n嵌套迭代指多次迭代列表项\n\n```yml\n- hosts: localhost\n  tasks:\n    - debug: msg=\"{{item[0]}} & {{item[1]}}\"\n      with_nested:\n        - [a,b]\n        - [1,2,3]\n\n结果将得到\"a & 1\"、\"a & 2\"、\"a & 3\"、\"b & 1\"、\"b & 2\"和\"b & 3\"共6个结果。\n```\n\n## 条件判断\n\nansible中，只有when可以实现条件判断。\n\n```yml\ntasks:\n- name: config the yum repo for centos 6\n  yum_repository:\n    name: epel\n    description: epel\n    baseurl: http://mirrors.aliyun.com/epel/6/$basearch/\n    gpgcheck: no\n  when: ansible_distribution_major_version == \"6\"\n```\n\n**注意：**\n\n- when判断的对象是task，所以和task在同⼀列表层次。它的判断结果决定它所在task是否执⾏，⽽不是它下⾯的task是否执⾏。\n- when中引⽤变量的时候不需要加{{ }}符号。\n\n此外还支持各种逻辑组合：\n\n```yml\ntasks:\n# 逻辑或\n- command: /sbin/shutdown -h now\n  when: (ansible_distribution == \"CentOS\" and ansible_distribution_major_version == \"6\") or\n        (ansible_distribution == \"Debian\" and ansible_distribution_major_version == \"7\")\n# 逻辑与\n- command: /sbin/shutdown -t now\n  when:\n    - ansible_distribution == \"CentOS\"\n    - ansible_distribution_major_version == \"6\"\n# 取反\n- command: /sbin/shutdown -t now\n  when: not ansible_distribution == \"CentOS\"\n```\n\n还可以直接引用布尔值的变量：\n\n```yml\n- hosts: localhost\n  vars:\n  epic: False\n  tasks:\n    - debug: msg=\"This certainly is epic!\"\n      when: not epic\n```","categoryId":3,"viewCount":1226,"categoryName":"Ansible","author":"球接子","authorAvatar":null,"tagIds":[3,6],"tagNames":["Ansible","Playbook"]}}