shell - 使用 Ansible 任务计算文件数量并删除除 10 个最新的文件之外的所有文件
问题描述
首先,我使用 shell 模块发送一个命令,该命令将计算每个路径中的文件数并将输出注册到一个变量中。
- name: Count files in backups
shell:
cmd: ls | wc -l
chdir: '{{ item }}'
with_items:
- '/home/backups/{{ domain_name }}/fullWP'
- '/home/backups/{{ domain_name }}/coreWP'
- '/home/backups/{{ domain_name }}/mysql'
- '/home/backups/{{ domain_name }}/archive'
- '/home/backups/{{ domain_name }}/config'
register: number_files
tags: clear.files
以下任务应该对目录中超过 10 个文件的每个文件路径运行一个命令。
- name: Delete the oldest backups
shell:
cmd: ls -t | tail -n +11 | xargs rm
chdir: '{{ item }}'
with_items:
- '/home/backups/{{ domain_name }}/fullWP'
- '/home/backups/{{ domain_name }}/coreWP'
- '/home/backups/{{ domain_name }}/mysql'
- '/home/backups/{{ domain_name }}/archive'
- '/home/backups/{{ domain_name }}/config'
when: number_files.stdout > 10 == true
tags: clear.oldFiles
我的错误告诉我我有一个未定义的变量,但不确定如何解决这个问题。
"msg": "The task includes an option with an undefined variable. The error was: 'dict object' has no attribute 'value'\n\
解决方案
例如,请参阅下面的剧本。
使用
find
模块创建文件列表result.files
。在下一个任务中创建
files_rm
要删除的文件的列表。按mtime
(atime
并且ctime
也可用) 对列表进行排序,映射属性path
并选择列表中的所有项目,但首先backup_keep
(10)。出于安全原因,默认情况下禁用文件的删除。
shell> cat pb.yml
- hosts: localhost
vars:
backup_dir: backups
backup_keep: 10
dry_run: true
tasks:
- find:
path: "{{ backup_dir }}"
register: result
- set_fact:
files_rm: "{{ (result.files|
sort(attribute='mtime', reverse=true)|
map(attribute='path')|
list)[backup_keep:] }}"
- debug:
var: files_rm
- file:
state: absent
path: "{{ item }}"
loop: "{{ files_rm }}"
when: not dry_run|bool
例子
让我们在目录中创建5个文件backups
shell> for i in {1..5}; do touch backups/backup-$i; done
shell> tree backups/
backups/
├── backup-1
├── backup-2
├── backup-3
├── backup-4
└── backup-5
0 directories, 5 files
为了测试,让我们设置backup_keep: 3
保留最后 3 个备份文件。剧本给出(删节)
shell> ansible-playbook pb.yml
TASK [debug] ****
ok: [localhost] =>
files_rm:
- backups/backup-2
- backups/backup-1
TASK [file] ****
skipping: [localhost] => (item=backups/backup-2)
skipping: [localhost] => (item=backups/backup-1)
这就是我们想要的。过时的 2 个备份文件将被删除。让我们删除文件。剧本给出(删节)
shell> ansible-playbook pb.yml -e "dry_run=False"
TASK [debug] ****
ok: [localhost] =>
files_rm:
- backups/backup-2
- backups/backup-1
TASK [file] ****
changed: [localhost] => (item=backups/backup-2)
changed: [localhost] => (item=backups/backup-1)
shell> tree backups/
backups/
├── backup-3
├── backup-4
└── backup-5
0 directories, 3 files
剧本是幂等的
shell> ansible-playbook pb.yml -e "dry_run=False"
ok: [localhost] =>
files_rm: []