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

如何用Ansible读取源文件内容,仅当内容不存在时追加至目标文件?

用Ansible实现仅添加目标文件中不存在的源文件内容

方法1:通用文本场景(lineinfile模块)

适用于任何文本文件的内容追加去重,完全替代示例中的shell命令且满足幂等性要求:

- name: 读取源文件内容
  slurp:
    src: /root/.ssh/authorized_keys
  register: source_keys

- name: 逐行添加源文件内容到目标文件(仅添加不存在的行)
  lineinfile:
    path: /home/foo/.ssh/authorized_keys
    line: "{{ item }}"
    state: present
    create: yes
    owner: foo
    group: foo
    mode: '0600'
  loop: "{{ (source_keys.content | b64decode).splitlines() }}"

关键说明:

  • slurp模块读取文件后返回Base64编码内容,需用b64decode解码为明文
  • lineinfile的state: present会自动检查目标文件是否存在该行,不存在则追加,存在则跳过
  • 显式设置owner、group、mode符合SSH密钥文件的权限规范(必须为600,属主为目标用户)

方法2:SSH密钥专属场景(authorized_key模块)

如果操作的是SSH授权密钥,使用专门的authorized_key模块更符合Ansible规范,它会自动处理重复密钥:

- name: 读取源文件内容
  slurp:
    src: /root/.ssh/authorized_keys
  register: source_keys

- name: 为foo用户添加SSH授权密钥(仅添加不存在的)
  authorized_key:
    user: foo
    key: "{{ item }}"
    state: present
  loop: "{{ (source_keys.content | b64decode).splitlines() }}"
  when: item | trim != ""

关键说明:

  • authorized_key模块会自动定位目标用户的authorized_keys文件路径,无需手动指定
  • 模块内置重复密钥检测逻辑,无需额外处理
  • when条件用于跳过源文件中的空行,避免无效操作

为什么不直接用shell模块?

  • 原生模块具备幂等性:重复执行不会导致内容重复追加,而示例中的>>命令每次执行都会追加内容,不符合Ansible最佳实践
  • 原生模块能自动处理权限、文件不存在等边界场景,执行结果更易被Ansible捕获和处理

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 22:54:20