如何在单个Ansible任务中组合json_query与basename过滤器?
单个Ansible任务中组合json_query与basename过滤器的解决方法
问题背景
原本通过两个set_fact任务处理文件路径:先用json_query('files[*].path')提取路径列表,再用basename获取文件名。但尝试直接串联两个过滤器时,触发错误expected str, bytes or os.PathLike object, not list,需要在单个任务中完成这两步操作。
原有可运行代码
- name: set_fact set_fact: filename: "{{ file1 | json_query('files[*].path') }}" - name: set_fact set_fact: filename: "{{ filename | basename }}"
错误尝试及对应报错
错误写法1
- name: set_fact set_fact: filename: "{{ file1 | json_query('files[*].path') | basename }}"
报错信息:
"msg": "Unexpected templating type error occurred on ({{ file1 | json_query('files[*].path') | basename }}): expected str, bytes or os.PathLike object, not list"
错误写法2
- name: set_fact set_fact: filename: "{{ (file1 | json_query('files[*].path')) | basename }}"
报错信息:
"msg": "Unexpected templating type error occurred on ({{ (file1 | json_query('files[*].path')) | basename }}): expected str, bytes or os.PathLike object, not list"
解决方法
核心问题是json_query('files[*].path')返回的是列表类型,而basename只能处理单个字符串路径,无法直接作用于列表。针对不同需求有两种处理方式:
1. 提取所有路径对应的文件名(保留列表)
用map过滤器遍历列表,对每个元素应用basename,最后转成列表:
- name: set_fact set_fact: filenames: "{{ file1 | json_query('files[*].path') | map('basename') | list }}"
2. 提取单个文件名(适用于files数组仅含一个元素)
可以直接用json_query定位到单个路径,再用basename:
- name: set_fact set_fact: filename: "{{ file1 | json_query('files[0].path') | basename }}"
或者先取列表第一个元素再处理:
- name: set_fact set_fact: filename: "{{ (file1 | json_query('files[*].path') | first) | basename }}"
内容的提问来源于stack exchange,提问作者Blitzden
相关产品推荐
相关产品推荐

