You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ansible如何遍历复杂嵌套字典计算多主机指定目录平均大小

问题原因
  • 变量名不匹配:你在汇总全量目录列表时调用了不存在的hostvars[item].dir_list变量,被管控节点上收集到的目录实际存储在log_list.stdout_lines中,这会直接导致all_dirs内容异常。
  • 工具选择错误:zip_longest的作用是对两个列表按位置配对生成键值对,和你需要的「单个目录遍历所有主机取对应大小」的两层遍历逻辑完全不匹配,强行使用会频繁触发key不存在的模板渲染错误。
修复实现

步骤1:修正汇总逻辑

先修正全量目录和主机目录信息的汇总代码,增加默认值避免部分主机无数据时执行报错:

- name: 汇总全量目录信息与唯一目录列表
  set_fact:
    all_dirs: "{{ all_dirs | default([]) + hostvars[item].log_list.stdout_lines | default([]) }}"
    all_folder_info: "{{ all_folder_info | default({}) | combine({hostvars[item].inventory_hostname: hostvars[item].folder_info | default({})}) }}"
  loop: "{{ groups['backoffice'] }}"

- name: 对全量目录列表去重
  set_fact:
    all_dirs: "{{ all_dirs | unique }}"

可选优化:如果存在同一目录路径有的带末尾斜杠、有的不带的情况,可以在被管控节点构建folder_info时统一对路径做标准化处理,把路径末尾的斜杠去掉,避免同一个目录被识别为两条不同数据:

# 替换原build dict任务中的combine部分即可
folder_info: "{{ folder_info|default({}) | combine({item.item | regex_replace('/$', ''): {'path': item.item | regex_replace('/$', ''), 'size': item.stdout|int}}) }}"

步骤2:计算目录平均大小

直接遍历全量目录列表,对每个目录统计所有主机上的有效大小,再计算平均值:

- name: 计算每个目录的平均大小
  set_fact:
    dir_avg_size: "{{ dir_avg_size | default({}) | combine({item: {'总大小_KB': total_size | int, '有该目录的主机数': host_count, '平均大小_KB': (total_size / host_count) | round(2)}}) }}"
  vars:
    # 提取所有主机上当前目录的大小,过滤掉不存在该目录的主机数据
    valid_size_list: "{{ groups['backoffice'] | map('extract', hostvars) | map(attribute='folder_info.' + item + '.size', default=0) | select('gt', 0) | list }}"
    total_size: "{{ valid_size_list | sum }}"
    host_count: "{{ valid_size_list | length }}"
  loop: "{{ all_dirs }}"

# 输出最终结果
- name: 打印各目录平均大小
  debug:
    var: dir_avg_size

最终输出的dir_avg_size会以目录路径为key,存储对应目录的总大小、统计的主机数量和平均大小,完全符合需求。

内容的提问来源于stack exchange,提问作者Gé Fa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 06:45:02