Ansible Playbook:文件名含随机部分时,如何仅在文件不存在时执行命令?
Ansible: 仅当匹配通配符/正则的文件不存在时执行命令
你遇到的问题核心在于:Ansible command模块的creates参数不支持正则或通配符匹配——它只会把你写的路径当成字面文件名去查找,而不是解析其中的[0-9]这类正则表达式。所以你写的K{{ item.name }}.+[0-9][0-9][0-9]+[0-9][0-9][0-9][0-9][0-9].key会被当作一个完整的文件名(包含方括号和加号)去查找,而实际生成的文件是带数字的,自然永远找不到,命令就会每次都执行。
下面给你两种可行的解决方案:
方案1:用stat模块提前检查(推荐,更安全)
先通过stat模块用glob通配符检查是否存在符合模式的文件,再用when条件控制命令执行:
- name: 检查DNS密钥文件是否存在 stat: path: "{{ target_zone_dir }}/K{{ item.name }}.+*.key" get_checksum: no # 不需要校验和,加快检查速度 register: dns_key_check with_items: "{{ target_zone_domains }}" - name: 生成DNS密钥文件 command: <command> "{{ item.item.name }}" chdir: "{{ target_zone_dir }}" check_mode: no with_items: "{{ dns_key_check.results }}" when: not item.stat.exists
说明:
stat模块的path支持*这类glob通配符,会自动检查是否有至少一个文件匹配该模式- 注册的
dns_key_check.results里,每个元素对应一个target_zone_domains中的项,item.stat.exists为True表示找到匹配文件,反之则执行命令
方案2:改用shell模块(更简洁,注意安全性)
shell模块的creates参数会通过系统shell解析通配符,所以可以直接用*代替你的正则部分:
- name: Generate file shell: <command> "{{ item.name }}" chdir: "{{ target_zone_dir }}" creates: "{{ target_zone_dir }}/K{{ item.name }}.+*.key" check_mode: no with_items: "{{ target_zone_domains }}"
注意:
shell模块会调用系统shell(比如bash)解析命令和路径,相比command模块安全性稍低——如果item.name可能包含空格、引号或其他特殊字符,需要确保正确转义,否则可能出现意料之外的行为- 只要匹配
K{{ item.name }}.+*.key的文件存在,命令就不会执行,同时你可以不用单独写.private文件的检查,因为生成密钥时这两个文件通常是成对出现的,检查其中一个即可
内容的提问来源于stack exchange,提问作者Dazul
相关产品推荐
相关产品推荐

