如何在Ansible中生成带时间戳的最新备份文件并复制至目标路径
我一眼就看出你的问题所在了:你当前用ansible_date_time.date作为备份文件的时间戳,这个变量只精确到日期(比如2019-08-19),所以同一天内多次运行Playbook时,新生成的备份会直接覆盖旧的同名文件。而复制到目标路径时,因为文件名完全相同,即便设置了force: yes,也达不到“复制最新备份”的预期——本质上你一直在复制同一个被反复覆盖的文件。
下面是针对性的解决方案:
1. 生成唯一命名的备份文件
把时间戳精度提高到时分秒,确保每次生成的备份文件名都是唯一的,不会覆盖旧文件。可以用ansible_date_time.iso8601(格式如2019-08-19T19:07:30),或者组合date+hour+minute+second自定义格式。
修改创建备份的任务:
- name: Create a unique backup file file: path: /test/backup_path/backup_{{ ansible_date_time.iso8601 }}.bkp state: touch mode: u=rw,g=r,o=r
这样生成的文件名会是类似backup_2019-08-19T19:07:30.bkp,完全不会重复。
2. 更可靠地获取最新备份文件
你之前用shell命令获取最新文件的方式虽然可行,但Ansible提供了更原生、跨平台的find模块,能避免依赖ls命令的输出格式差异:
- name: Get the latest backup file find: path: /test/backup_path patterns: "backup_*.bkp" # 匹配所有备份文件 sort: yes order: lastmodified # 按修改时间倒序排列 limit: 1 # 只取最新的一个文件 register: latest_bkp - debug: msg="Latest backup file is {{ latest_bkp.files[0].path }}"
3. 简化复制任务
因为find模块已经直接返回了最新文件的完整路径,你不需要再用with_items,直接引用路径即可:
- name: Copy the latest backup to restore path copy: src: "{{ latest_bkp.files[0].path }}" dest: /test/restore_path/ remote_src: yes owner: root group: root mode: '0644' force: yes
修改后的完整Playbook
# Generate unique backup and copy latest to restore path - name: Create a unique backup file file: path: /test/backup_path/backup_{{ ansible_date_time.iso8601 }}.bkp state: touch mode: u=rw,g=r,o=r - name: Get the latest backup file find: path: /test/backup_path patterns: "backup_*.bkp" sort: yes order: lastmodified limit: 1 register: latest_bkp - debug: msg="Latest backup file is {{ latest_bkp.files[0].path }}" - name: Copy the latest backup to restore path copy: src: "{{ latest_bkp.files[0].path }}" dest: /test/restore_path/ remote_src: yes owner: root group: root mode: '0644' force: yes
效果验证
现在每次运行Playbook,都会在/test/backup_path生成一个全新命名的备份文件,find模块会精准定位到最新的那个,然后复制到目标路径——即使目标路径已有旧的备份文件,force: yes会自动覆盖,且因为文件名唯一,你能清晰区分不同时间点的备份文件。
内容的提问来源于stack exchange,提问作者Maheswara Reddy Yarramreddy

