如何用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
相关产品推荐
相关产品推荐

