Ansible 2.3查找文件并复制时遇'files'属性不存在错误求助
解决Ansible 2.3中
find结果引用导致的'dict object' has no attribute 'files'错误 这个报错我在Ansible早期版本的排查中碰到过很多次,根源是你对find模块返回的结果结构理解有误,直接调用了不存在的files属性。咱们一步步来解决:
1. 先搞清楚Ansible 2.3中find模块的返回结构
在Ansible 2.3里,find模块执行后注册的变量是一个字典,真正的文件列表嵌套在results字段的子元素里。举个例子,假设你注册的变量叫found_files,它的结构大概是这样的:
{ "changed": false, "examined": 15, "failed": false, "matched": 3, "results": [ { "files": [ {"path": "/opt/target/fileA.log", ...}, {"path": "/opt/target/fileB.log", ...} ], "path": "/opt/target", ...其他字段 } ] }
你之前直接用{{ found_files.files }}肯定会报错,因为files属性根本不在顶层字典里,而是在results[0].files里(单台主机执行的情况下,results是只有一个元素的列表)。
2. 修正你的复制任务
假设你的find任务是这样的:
- name: 查找匹配模式的文件 find: paths: "/your/target/directory" patterns: "your-pattern-*" recurse: yes # 如果需要递归查找的话 register: found_files
那对应的复制任务要改成遍历results[0].files里的每个文件路径:
- name: 复制找到的文件到目标路径 copy: src: "{{ item.path }}" dest: "/your/destination/directory/" remote_src: yes # 如果源文件在远程主机上,必须加这个参数! loop: "{{ found_files.results[0].files }}"
这里要注意:如果你的源文件是在远程主机上,一定要加上remote_src: yes,否则Ansible会默认从控制节点找文件,也会导致错误。
3. 特殊情况:多主机执行find
如果你的find任务是在多台主机上运行的,results列表会包含对应每台主机的结果元素。这时候你需要根据实际需求调整遍历逻辑,比如针对每台主机的结果分别处理:
- name: 逐主机复制找到的文件 copy: src: "{{ item.1.path }}" dest: "/dest/on/{{ item.0.inventory_hostname }}/" loop: "{{ found_files.results | subelements('files') }}"
4. 验证结果的小技巧
你可以在复制任务前加一个debug任务,明确打印出要遍历的文件列表,确保引用正确:
- name: 打印找到的文件路径 debug: msg: "要复制的文件: {{ item.path }}" loop: "{{ found_files.results[0].files }}"
内容的提问来源于stack exchange,提问作者firasKoubaa
相关产品推荐
相关产品推荐

