首页 > 解决方案 > 使用 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\

标签: shellansible

解决方案


例如,请参阅下面的剧本。

  • 使用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: []

推荐阅读