如何使用Ansible删除指定目录下除少数子目录外的所有子目录?
优雅实现Ansible删除指定目录下非保留子目录
方法一:利用Ansible模块+Jinja2过滤(推荐,符合Ansible最佳实践)
通过find模块收集目录列表,结合Jinja2的集合过滤能力,直接筛选出需删除的目录批量处理,避免冗长循环:
- name: 收集目标目录下的一级子目录 ansible.builtin.find: path: /your/target/directory file_type: directory recurse: no # 仅处理一级子目录,需递归则改为yes register: target_subdirs - name: 删除不在保留列表中的子目录 ansible.builtin.file: path: "{{ item }}" state: absent loop: > {{ target_subdirs.files | map(attribute='path') | list | difference(subfolders_to_keep | map('regex_replace', '^', '/your/target/directory/') | list) }} when: target_subdirs.files | length > 0
说明:
map(attribute='path')提取find返回的目录绝对路径difference过滤器对比保留列表(先将相对路径转为绝对路径格式),得到需删除的目录集合when条件避免无目录时执行空循环
方法二:结合Shell命令快速处理(适合熟悉Linux命令的场景)
利用find+rm的组合命令,通过参数排除保留目录,一次性完成删除:
- name: 删除非保留子目录 ansible.builtin.command: > find /your/target/directory -maxdepth 1 -type d ! -name "." {% if subfolders_to_keep | length > 0 %} {% for dir in subfolders_to_keep %}! -name "{{ dir }}" {% endfor %} {% endif %} -exec rm -rf {} + args: warn: false # 关闭rm命令的安全警告 when: subfolders_to_keep is defined
说明:
-maxdepth 1限制仅处理一级子目录,需递归则移除该参数- 通过Jinja2循环生成
! -name参数,排除所有需保留的目录 - 测试阶段可将
rm -rf替换为echo,先验证要删除的目录是否正确
注意事项
- 确保
subfolders_to_keep中的路径格式统一:若用相对路径,需和目标目录拼接为绝对路径(方法一已处理);若直接传入绝对路径,可简化过滤器逻辑 - 递归删除时需谨慎,避免误删深层目录
- 生产环境建议先通过
debug模块输出需删除的目录列表,确认无误后再执行删除操作
内容的提问来源于stack exchange,提问作者Mikhail T.
相关产品推荐
相关产品推荐

