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

如何在Ansible中仅对JSON文件指定的主机执行命令?

解决思路与实现步骤

第一步:修正并优化JSON文件读取逻辑

你原来的shell命令存在错误(直接执行文件路径会报错),这里提供两种可靠的读取方式:

方式1:用Ansible原生模块(无需依赖jq)

推荐用slurp读取文件,再用Ansible内置的JSON解析能力处理,避免对jq的依赖:

- name: 读取host1上的/tmp/hosts.json
  slurp:
    src: /tmp/hosts.json
  register: json_content
  when: inventory_hostname == groups['group1'][0]
  run_once: true  # 仅在host1上执行一次

- name: 解析JSON提取目标主机列表
  set_fact:
    target_hosts: "{{ (json_content.content | b64decode | from_json) | map(attribute='hostName') | list }}"
  run_once: true
  delegate_to: localhost  # 将变量存到控制节点,让所有主机都能访问

方式2:保留shell+jq的方式(需处理引号)

如果坚持用jq,要修正命令并清理输出中的引号:

- name: 读取host1上的/tmp/hosts.json
  shell: cat /tmp/hosts.json | jq '.[].hostName'
  register: data
  when: inventory_hostname == groups['group1'][0]
  run_once: true

- name: 清理主机名的引号并生成列表
  set_fact:
    target_hosts: "{{ data.stdout_lines | map('replace', '\"', '') | list }}"
  run_once: true
  delegate_to: localhost

第二步:在指定主机上执行命令

通过when条件判断当前主机是否在目标列表中,即可实现仅在指定主机执行任务:

- name: 在目标主机执行ls /tmp
  shell: ls /tmp
  when: inventory_hostname in target_hosts

关键注意点

  • run_once: true:确保读取文件的任务只执行一次,避免重复操作
  • delegate_to: localhost:将目标主机列表变量存储在控制节点,让所有被管理主机都能引用该变量
  • 最终要得到无引号的主机名字符串数组,这样inventory_hostname in target_hosts才能正确匹配

内容的提问来源于stack exchange,提问作者Alatau

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 01:27:23