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

Ansible lineinfile模块无法完整写入所有输出问题排查

问题描述

我写了一个Ansible Playbook,要执行命令sudo /usr/sbin/dmidecode -t1 | grep -i vmware | grep -i product,然后用lineinfile模块把结果写入本地文件/home/myuser/ansible/mine/vmware.out。批量多主机执行时,debug模块显示每个主机的结果都正确,但目标文件里只包含部分主机的记录;必须重复执行两次Playbook,文件才能完整写入所有记录。调整多次都没解决,-v/-vv日志也没异常。

附sudo dmidecode -t1命令输出:

# dmidecode 3.2
Getting SMBIOS data from sysfs.
SMBIOS 2.4 present.

Handle 0x0001, DMI type 1, 27 bytes
System Information
        Manufacturer: VMware, Inc.
        Product Name: VMware Virtual Platform
        Version: None
        Serial Number: VMware-42 15 27 29 d2 1d 0b 1e-ec 62 1a 6b a1 f2 af 11
        UUID: 12165229-d21d-0b0e-ec63-1b6aa2e7nf92
        Wake-up Type: Power Switch
        SKU Number: Not Specified
        Family: Not Specified

问题根源

lineinfile模块默认是并行执行的,当多个主机同时往本地同一个文件写入时,会触发文件写入竞争——多个进程同时打开、修改文件,后执行的进程会覆盖或打断前一个进程的写入操作,导致部分记录丢失。第二次执行时,那些第一次没写入成功的主机重新执行写入,才会补全记录。

解决方案

方案1:改用fetch+assemble模块(推荐)

先把每个主机的结果收集到控制节点的临时目录,再合并成一个文件,彻底规避写入竞争:

- name: 收集VMware产品信息
  hosts: all
  tasks:
    - name: 执行dmidecode命令获取产品信息
      command: sudo /usr/sbin/dmidecode -t1 | grep -i vmware | grep -i product
      register: vmware_product

    - name: 将结果写入主机临时文件
      copy:
        content: "{{ vmware_product.stdout }} ({{ inventory_hostname }})"
        dest: /tmp/vmware_{{ inventory_hostname }}.out

    - name: 拉取临时文件到控制节点
      fetch:
        src: /tmp/vmware_{{ inventory_hostname }}.out
        dest: /tmp/vmware_results/
        flat: yes

- name: 合并所有主机记录到目标文件
  hosts: localhost
  tasks:
    - name: 合并文件
      assemble:
        src: /tmp/vmware_results/
        dest: /home/myuser/ansible/mine/vmware.out
        regexp: '^vmware_.*\.out$'

    - name: 清理临时文件
      file:
        path: /tmp/vmware_results/
        state: absent

方案2:给lineinfile添加串行执行控制

通过run_once: true配合遍历所有主机的结果,让写入操作在控制节点串行执行,避免竞争:

- name: 收集并写入VMware产品信息
  hosts: all
  tasks:
    - name: 执行dmidecode命令获取产品信息
      command: sudo /usr/sbin/dmidecode -t1 | grep -i vmware | grep -i product
      register: vmware_product

- name: 将所有结果写入本地文件
  hosts: localhost
  tasks:
    - name: 串行写入每条记录
      lineinfile:
        path: /home/myuser/ansible/mine/vmware.out
        line: "{{ item.stdout }} ({{ item.inventory_hostname }})"
        create: yes
      with_items: "{{ hostvars | dict2items | map(attribute='value.vmware_product') }}"

方案3:使用copy模块一次性写入所有结果

先收集所有主机的结果到一个变量,再一次性写入文件,同样避免并行写入:

- name: 收集VMware产品信息
  hosts: all
  tasks:
    - name: 执行dmidecode命令获取产品信息
      command: sudo /usr/sbin/dmidecode -t1 | grep -i vmware | grep -i product
      register: vmware_product

- name: 批量写入所有记录
  hosts: localhost
  tasks:
    - name: 生成所有记录内容
      set_fact:
        all_vmware_records: |
          {% for host in groups['all'] %}
          {{ hostvars[host].vmware_product.stdout }} ({{ host }})
          {% endfor %}

    - name: 写入目标文件
      copy:
        content: "{{ all_vmware_records }}"
        dest: /home/myuser/ansible/mine/vmware.out
        force: yes

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 15:40:27