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

如何在Ansible中将Zabbix配置命令输出转换为字典?

问题描述

我正在解析Zabbix配置文件以提取变量,本来可以拆分成多个独立任务完成,但我想在单个任务里实现。需要把命令输出转换成字典,请问该如何从文件中注册这些变量?

我的Ansible角色任务文件如下:

# tasks file for roles/test
- name: Read vars
  shell: egrep -v -e "^#|^$" /etc/zabbix/zabbix_agentd.conf
  register: zbaconfig

- name: Debug 1
  debug:
    msg:
      - "{{ zbaconfig.stdout_lines }}"

- name: Register vars
  set_fact:
    zba: "{{ dict(zbaconfig.stdout | split('\\n') | select() | map('split','=') | list) }}"

- name: Debug 2
  debug:
    msg:
      - "{{ zba.Hostname }}"
      - "{{ zba.ServerActive }}"
      - "{{ zba.Server }}"

执行后报错信息如下:

TASK [test : Debug 1] 
ok: [10.100.0.52] => {
        "msg": [
        [
            "PidFile=/run/zabbix/zabbix_agentd.pid",
            "LogFile=/var/log/zabbix/zabbix_agentd.log",
            "LogFileSize=0",
            "Server=zabbix.domain.com.ua",
            "ServerActive=zabbix.domain.com.ua",
            "Hostname=vs-net-dk01",
            "Include=/etc/zabbix/zabbix_agentd.d/*.conf"
        ],

TASK [test : Register vars] 
fatal: [10.100.0.52]: FAILED! => {"msg": "template error while templating string: no filter named 'split'. String: {{ dict(zbaconfig.stdout | split('\n') | select() | map('split','=') | list) }}"}
解决方案

报错核心原因是Jinja2模板中不存在split过滤器,正确的做法是使用字符串原生的split()方法,或者直接利用shell模块返回的stdout_lines字段(该字段已自动将输出按换行分割为列表)。

最简修改方案

直接修改Register vars任务,利用已有的stdout_lines:

- name: Register vars
  set_fact:
    zba: "{{ dict(zbaconfig.stdout_lines | map('split', '=') | list) }}"

说明:

  • zbaconfig.stdout_lines已经是过滤掉空行和注释后的行列表(因为shell命令用了egrep -v "^#|^$"),无需额外过滤空行。
  • map('split', '=')将每一行按=分割为键值对子列表。
  • dict()将子列表转换为字典,之后即可通过zba.Hostname这类方式直接访问配置项。

处理含多个=的配置行

如果配置值中包含=(比如自定义参数),可以限制仅分割第一个=,避免破坏值的完整性:

- name: Register vars
  set_fact:
    zba: "{{ dict(zbaconfig.stdout_lines | map('split', '=', 1) | list) }}"

更符合Ansible最佳实践的方案

无需依赖目标主机的egrep命令,用slurp模块读取文件后本地处理:

- name: Read remote Zabbix config
  slurp:
    src: /etc/zabbix/zabbix_agentd.conf
  register: zbaconfig_raw

- name: Parse config to dict
  set_fact:
    zba: >-
      {{
        dict(
          zbaconfig_raw.content | b64decode
          | split('\n')
          | reject('match', '^#')
          | reject('match', '^$')
          | map('split', '=', 1)
          | list
        )
      }}

内容的提问来源于stack exchange,提问作者Андрей Курочкин

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 23:01:24