190

下面的代码只删除它在 web 目录中的第一个文件。我想删除 web 目录中的所有文件和文件夹并保留 web 目录。我怎样才能做到这一点?

- name: remove web dir contents
    file: path='/home/mydata/web/{{ item }}' state=absent
    with_fileglob:
      - /home/mydata/web/*

注意:我尝试过rm -rf使用命令和 shell,但它们不起作用。也许我错误地使用它们。

任何正确方向的帮助将不胜感激。

我正在使用 ansible 2.1.0.0

4

18 回答 18

171
- name: Delete content & directory
  file:
    state: absent
    path: /home/mydata/web/

注意:这也会删除目录。

于 2016-07-05T10:49:35.820 回答
89

使用 shell 模块(也是幂等的):

- shell: /bin/rm -rf /home/mydata/web/*

如果有点/隐藏文件:

- shell: /bin/rm -rf /home/mydata/web/* /home/mydata/web/.*

如果您不关心创建日期和所有者/权限,最干净的解决方案:

- file: path=/home/mydata/web state=absent
- file: path=/home/mydata/web state=directory
于 2016-07-05T10:54:14.263 回答
86

删除目录(基本上是https://stackoverflow.com/a/38201611/1695680的副本),Ansible 在后台执行此操作rmtree

- name: remove files and directories
  file:
    state: "{{ item }}"
    path: "/srv/deleteme/"
    owner: 1000  # set your owner, group, and mode accordingly
    group: 1000
    mode: '0777'
  with_items:
    - absent
    - directory

如果您没有删除整个目录并重新创建它的奢侈,您可以扫描它以查找文件(和目录),然后一一删除。这需要一段时间。你可能想确保你[ssh_connection]\npipelining = True在你的 ansible.cfg 上。

- block:
  - name: 'collect files'
    find:
      paths: "/srv/deleteme/"
      hidden: True
      recurse: True
      # file_type: any  # Added in ansible 2.3
    register: collected_files

  - name: 'collect directories'
    find:
      paths: "/srv/deleteme/"
      hidden: True
      recurse: True
      file_type: directory
    register: collected_directories

  - name: remove collected files and directories
    file:
      path: "{{ item.path }}"
      state: absent
    with_items: >
      {{
        collected_files.files
        + collected_directories.files
      }}
于 2017-01-24T19:20:47.213 回答
42

我真的不喜欢 rm 解决方案,而且 ansible 也会给你关于使用 rm 的警告。所以这里是如何在不需要 rm 并且没有 ansible 警告的情况下做到这一点。

- hosts: all
  tasks:
  - name: Ansible delete file glob
    find:
      paths: /etc/Ansible
      patterns: "*.txt"
    register: files_to_delete

  - name: Ansible remove file glob
    file:
      path: "{{ item.path }}"
      state: absent
    with_items: "{{ files_to_delete.files }}"

来源:http ://www.mydailytutorials.com/ansible-delete-multiple-files-directories-ansible/

于 2018-07-31T06:51:00.130 回答
18

尝试以下命令,它应该可以工作

- shell: ls -1 /some/dir
  register: contents

- file: path=/some/dir/{{ item }} state=absent
  with_items: {{ contents.stdout_lines }}
于 2016-07-05T12:04:00.873 回答
9

这就是我想出的:

- name: Get directory listing
  find:
    path: "{{ directory }}" 
    file_type: any
    hidden: yes
  register: directory_content_result

- name: Remove directory content
  file:
    path: "{{ item.path }}" 
    state: absent
  with_items: "{{ directory_content_result.files }}" 
  loop_control:
    label: "{{ item.path }}" 

首先,我们使用find, 设置获取目录列表

  • file_typeto any,所以我们不会错过嵌套的目录和链接
  • hiddento yes,所以我们不会跳过隐藏文件
  • 另外,不要设置recurseyes,因为它不仅没有必要,而且可能会增加执行时间。

然后,我们使用file模块浏览该列表。它的输出有点冗长,因此loop_control.label将帮助我们限制输出(在此处找到此建议)。


但是我发现以前的解决方案有点慢,因为它会遍历内容,所以我选择了:

- name: Get directory stats
  stat:
    path: "{{ directory }}"
  register: directory_stat

- name: Delete directory
  file:
    path: "{{ directory }}"
    state: absent

- name: Create directory
  file:
    path: "{{ directory }}"
    state: directory
    owner: "{{ directory_stat.stat.pw_name }}"
    group: "{{ directory_stat.stat.gr_name }}"
    mode: "{{ directory_stat.stat.mode }}"
  • 获取目录属性stat
  • 删除目录
  • 重新创建具有相同属性的目录。

这对我来说已经足够了,但attributes如果你愿意,你也可以添加。

于 2019-09-22T17:18:04.770 回答
5

从所有意见和建议中创建了一个经过全面改造和故障安全的实施:

# collect stats about the dir
- name: check directory exists
  stat:
    path: '{{ directory_path }}'
  register: dir_to_delete

# delete directory if condition is true
- name: purge {{directory_path}}
  file:
    state: absent
    path: '{{ directory_path  }}'
  when: dir_to_delete.stat.exists and dir_to_delete.stat.isdir

# create directory if deleted (or if it didn't exist at all)
- name: create directory again
  file:
    state: directory
    path: '{{ directory_path }}'
  when: dir_to_delete is defined or dir_to_delete.stat.exist == False
于 2018-06-28T08:04:25.970 回答
4

使用文件 glob 也可以。您发布的代码中有一些语法错误。我已经修改并测试了这应该可以工作。

- name: remove web dir contents
  file:
    path: "{{ item }}"
    state: absent
  with_fileglob:
    - "/home/mydata/web/*"
于 2016-07-06T09:14:33.700 回答
3

下面的代码对我有用:

- name: Get directory listing
  become: yes
  find:
    paths: /applications/cache
    patterns: '*'
    hidden: yes
  register: directory_content_result

- name: Remove directory content
  become: yes
  file:
    path: "{{ item.path }}"
    state: absent
  with_items: "{{ directory_content_result.files }}"
于 2021-02-01T13:35:47.200 回答
3

虽然 Ansible 仍在争论如何实施state = empty https://github.com/ansible/ansible-modules-core/issues/902

my_folder: "/home/mydata/web/"
empty_path: "/tmp/empty"


- name: "Create empty folder for wiping."
  file:
    path: "{{ empty_path }}" 
    state: directory

- name: "Wipe clean {{ my_folder }} with empty folder hack."
  synchronize:
    mode: push

    #note the backslash here
    src: "{{ empty_path }}/" 

    dest: "{{ nl_code_path }}"
    recursive: yes
    delete: yes
  delegate_to: "{{ inventory_hostname }}"

但是请注意,通过同步,您应该能够正确同步您的文件(使用删除)。

于 2017-10-10T11:47:55.543 回答
1

对此有一个未解决的问题

目前,该解决方案适用于我:在本地创建一个空文件夹并将其与远程文件夹同步。

这是一个示例剧本:

- name: "Empty directory"
  hosts: *
  tasks:
    - name: "Create an empty directory (locally)"
      local_action:
        module: file
        state: directory
        path: "/tmp/empty"

    - name: Empty remote directory
      synchronize:
        src: /tmp/empty/
        dest: /home/mydata/web/
        delete: yes
        recursive: yes
于 2017-11-14T05:33:17.537 回答
1

我编写了一个自定义的 ansible 模块来清理基于多个过滤器(如年龄、时间戳、glob 模式等)的文件。

它还与 ansible 旧版本兼容。可以在这里找到。

这是一个例子:

- cleanup_files:
  path_pattern: /tmp/*.log
  state: absent
  excludes:
    - foo*
    - bar*
于 2019-05-08T22:35:33.273 回答
0

如果您使用的是 Ansible >= 2.3(不再需要区分文件和目录),则只需一个小的 ThorSummoners 答案的更干净的复制和粘贴模板。

- name: Collect all fs items inside dir
  find:
    path: "{{ target_directory_path }}"
    hidden: true
    file_type: any
  changed_when: false
  register: collected_fsitems
- name: Remove all fs items inside dir
  file:
    path: "{{ item.path }}"
    state: absent
  with_items: "{{ collected_fsitems.files }}"
  when: collected_fsitems.matched|int != 0
于 2019-05-22T08:30:59.680 回答
0

我想确保 find 命令只删除目录中的所有内容并保持目录完好无损,因为在我的情况下,目录是一个文件系统。尝试删除文件系统时系统会产生错误,但这不是一个好的选择。我正在使用 shell 选项,因为这是迄今为止我为这个问题找到的唯一可行的选项。

我做了什么:

编辑 hosts 文件以放入一些变量:

[all:vars]
COGNOS_HOME=/tmp/cognos
find=/bin/find

并创建一个剧本:

- hosts: all
  tasks:
  - name: Ansible remove files
    shell: "{{ find }} {{ COGNOS_HOME }} -xdev -mindepth 1 -delete"

这将删除 COGNOS_HOME 变量目录/文件系统中的所有文件和目录。“-mindepth 1”选项确保不会触及当前目录。

于 2018-10-09T12:11:54.683 回答
0

是不是很简单...测试工作..

例如。

---
- hosts: localhost
  vars:
     cleandir: /var/lib/cloud/
  tasks:
   - shell: ls -a -I '.' -I '..' {{ cleandir }}
     register: ls2del
     ignore_errors: yes
   - name: Cleanup {{ cleandir }}
     file:
       path: "{{ cleandir }}{{ item }}"
       state: absent
     with_items: "{{ ls2del.stdout_lines }}"
于 2020-12-13T11:56:10.353 回答
-1

假设您总是在 Linux 中,请尝试使用findcmd。

- name: Clean everything inside {{ item }}
  shell: test -d {{ item }} && find {{ item }} -path '{{ item }}/*' -prune -exec rm -rf {} \;
  with_items: [/home/mydata/web]

这应该清除文件/文件夹/隐藏在/home/mydata/web

于 2017-01-25T02:12:02.283 回答
-2
删除的目录,然后创建该目录,使用在循环
  - name: delete old data and clean cache
    file:
      path: "{{ item[0] }}" 
      state: "{{ item[1] }}"
    with_nested:
      - [ "/data/server/{{ app_name }}/webapps/", "/data/server/{{ app_name }}/work/" ]
      - [ "absent", "directory" ]
    ignore_errors: yes
于 2018-08-14T15:01:20.163 回答
-6

下面为我​​工作,

- name: Ansible delete html directory
  file:
   path: /var/www/html
   state: directory
于 2017-09-25T12:33:10.743 回答