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

Ansible使用lineinfile模块追加主机名至文件时内容缺失

问题根源

你碰到的是多进程文件竞争导致的问题:你的playbook会对--limit指定的每台主机单独执行lineinfile任务,这些任务是并行运行的——多个进程同时打开、修改、保存newDevices.txt,部分写入操作会被覆盖,最终出现内容随机缺失的情况。lineinfile模块本身单进程下是安全的,但扛不住多进程同时操作同一个文件。

修复方案

把写入主机名的任务改成仅执行一次,通过循环遍历目标主机列表批量写入,彻底规避并行竞争。修改后的playbook如下:

- name: Setting some variables.
  hosts: "{{ target }}"
  gather_facts: no
  connection: local
  
  tasks:
    - name: Delete and recreate newDevices file.
      file:
        path: newDevices.txt
        state: absent
      run_once: true

    - name: Create empty newDevices file.
      file:
        path: newDevices.txt
        state: touch
        mode: '0644'
      run_once: true

    - name: Add all target devices to file in one go
      lineinfile:
        path: newDevices.txt
        line: "{{ item }}"
      loop: "{{ ansible_play_hosts_all }}"
      delegate_to: 127.0.0.1
      run_once: true

方案说明

  1. 保留原有的删、建文件逻辑,用run_once确保只执行一次
  2. 核心修改:ansible_play_hosts_all变量会返回当前play实际执行的所有主机(包含--limit过滤后的结果),通过loop遍历这个列表,一次性把所有主机名写入文件,全程仅执行一次写入操作,完全避免并行竞争
更简洁的替代写法

如果不需要保留lineinfile的幂等性(比如每次都要生成全新的文件),可以直接用copy模块生成文件,效率更高:

- name: Setting some variables.
  hosts: "{{ target }}"
  gather_facts: no
  connection: local
  
  tasks:
    - name: Generate newDevices.txt with all target hosts
      copy:
        content: "{{ ansible_play_hosts_all | join('\n') }}\n"
        dest: newDevices.txt
        mode: '0644'
      delegate_to: 127.0.0.1
      run_once: true

这个写法直接把所有主机名拼接成字符串,一次性写入文件,完全不会有竞争问题,代码也更简洁。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 11:48:20