Ansible:如何删除目录中的文件和文件夹?

Abb*_*bas 137 delete-file ansible delete-directory

以下代码仅删除它在Web目录中获取的第一个文件.我想删除web目录中的所有文件和文件夹并保留web目录.我怎样才能做到这一点?

  - name: remove web dir contents
     file: path='/home/mydata/web/{{ item }}' state=absent
     with_fileglob:
       - /home/mydata/web/*
Run Code Online (Sandbox Code Playgroud)

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

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

我使用的是ansible 2.1.0.0

Moh*_*r P 130

下面的代码将删除artifact_path的全部内容

- name: Clean artifact path
  file:
    state: absent
    path: "{{ artifact_path }}/"
Run Code Online (Sandbox Code Playgroud)

注意:这也会删除目录.

  • OP(和我自己)想要一个解决方案,它将删除文件夹的内容而不是文件夹本身.此解决方案删除内容和文件夹本身. (65认同)
  • 如果artifact_path为null,是否有人将上述代码失败?这感觉它可能容易受到历史上那些伟大的"rm -rf /"时刻之一的影响 (15认同)
  • 这是如何得到一个upvote?这也会删除目录. (13认同)
  • 报价不是必需的.这只是我的工作代码.artifact_path就像/ app/my_app/work / (3认同)
  • @ ted-k42为了安全,我会做这样的事情:`when:artifact_path是定义的,artifact_path!=""` (2认同)

hel*_*loV 66

使用shell模块:

- shell: /bin/rm -rf /home/mydata/web/*
Run Code Online (Sandbox Code Playgroud)

如果您不关心创建日期,最干净的解决方案:

- file: path=/home/mydata/web state=absent
- file: path=/home/mydata/web state=directory
Run Code Online (Sandbox Code Playgroud)

  • 但无法删除以.开头的文件.像.htaccess (7认同)
  • @Ocab19 rm -rf [variable]/* 是一个有风险的操作。我不推荐它。如果 [变量] 为空怎么办?这变成了 rm -rf /*。尽管许多服务器都阻止了这种情况,但它可能会导致灾难。 (7认同)
  • 通配符不能与命令一起使用,因为它们需要shell进行扩展 (4认同)

Tho*_*ner 49

删除目录(基本上是/sf/answers/2674112801/的副本),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
Run Code Online (Sandbox Code Playgroud)

如果您没有删除整个目录并重新创建它的奢侈,您可以扫描它以查找文件,(和目录),并逐个删除它们.这需要一段时间.您可能希望确保[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
      }}
Run Code Online (Sandbox Code Playgroud)

  • 第一项任务是我见过的最优雅的解决方案.注意其他地方的注释,有一个长期运行的功能请求添加`state = empty` (4认同)

Cri*_*ris 20

我真的不喜欢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 }}"
Run Code Online (Sandbox Code Playgroud)

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

  • 然而这个问题的最佳解决方案! (2认同)
  • 这也会删除文件夹“item.path” (2认同)

小智 18

尝试下面的命令,它应该工作

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

- file: path=/some/dir/{{ item }} state=absent
  with_items: {{ contents.stdout_lines }}
Run Code Online (Sandbox Code Playgroud)

  • 你错过了使用{{,}}正确地逃避最后一行以获得`with_items:"{{contents.stdout_lines}}"` (3认同)
  • 使用“ls”输出来获取文件名是危险的,因为它不能正确打印带有特殊字符(例如换行符)的文件名。 (2认同)

Ale*_*der 8

这就是我想出的:

- 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 }}" 
Run Code Online (Sandbox Code Playgroud)

首先,我们使用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 }}"
Run Code Online (Sandbox Code Playgroud)
  • 获取目录属性 stat
  • 删除目录
  • 重新创建具有相同属性的目录。

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


Dee*_*tal 6

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

- name: remove web dir contents
  file:
    path: "{{ item }}"
    state: absent
  with_fileglob:
    - "/home/mydata/web/*"
Run Code Online (Sandbox Code Playgroud)

  • `with_fileglob`只适用于本地机器,不适用于远程机器; 不是吗? (11认同)

小智 6

跟进此处最受好评的答案(由于“编辑队列已满”,我无法编辑该答案):

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

- name: Re-create the directory
  file:
    state: directory
    path: /home/mydata/web/
Run Code Online (Sandbox Code Playgroud)

  • 请注意,您可能需要添加“所有者”和/或“组”和/或“模式”以使用正确的所有权和权限重新创建目录。 (2认同)

Mar*_*cin 5

虽然 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 }}"
Run Code Online (Sandbox Code Playgroud)

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


Mar*_*kus 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
Run Code Online (Sandbox Code Playgroud)