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

Ansible:如何删除目录中的文件和文件夹?,ansible,delete-file,delete-directory,Ansible,Delete File,Delete Directory,下面的代码只删除它在web目录中得到的第一个文件。我想删除web目录中的所有文件和文件夹,并保留web目录。我该怎么做 -名称:删除web目录内容 文件:路径='/home/mydata/web/{{item}}'状态=缺席 使用_fileglob: -/home/mydata/web/* 注意:我尝试过使用命令和shellrm-rf,但它们不起作用。也许我用错了 任何方向正确的帮助都将不胜感激 我正在使用ansible 2.1.0.0-名称:删除内容和目录 文件: 国家:缺席 路径:/hom

下面的代码只删除它在web目录中得到的第一个文件。我想删除web目录中的所有文件和文件夹,并保留web目录。我该怎么做

-名称:删除web目录内容
文件:路径='/home/mydata/web/{{item}}'状态=缺席
使用_fileglob:
-/home/mydata/web/*
注意:我尝试过使用命令和shell
rm-rf
,但它们不起作用。也许我用错了

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

我正在使用ansible 2.1.0.0

-名称:删除内容和目录
文件:
国家:缺席
路径:/home/mydata/web/
注意:这也将删除目录。

使用shell模块(幂等元):

如果存在点/隐藏文件:

- shell: /bin/rm -rf /home/mydata/web/* /home/mydata/web/.*
最干净的解决方案如果您不关心创建日期和所有者/权限:

- file: path=/home/mydata/web state=absent
- file: path=/home/mydata/web state=directory

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

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

- file: path=/some/dir/{{ item }} state=absent
  with_items: {{ contents.stdout_lines }}

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

- name: remove web dir contents
  file:
    path: "{{ item }}"
    state: absent
  with_fileglob:
    - "/home/mydata/web/*"
删除目录(基本上是的副本),Ansible在引擎盖下执行此操作

- 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

如果您没有足够的时间删除整个目录并重新创建它,您可以扫描其中的文件(和目录),然后逐个删除它们。这需要一段时间。您可能希望确保您的ansible.cfg中有
[ssh\u connection]\npipeling=True

- 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
      }}

假设您一直使用Linux,请尝试
find
cmd

- 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

- name: Ansible delete html directory
  file:
   path: /var/www/html
   state: directory

而Ansible仍在讨论如何实现
state=empty

不过请注意,使用“同步”,您应该能够正确地同步您的文件(使用“删除”。

对此有一个明确的定义

目前,解决方案对我来说很有效:在本地创建一个空文件夹,并将其与远程文件夹同步

以下是一个示例剧本:

- 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
- hosts: all
  tasks:
  - name: Ansible remove files
    shell: "{{ find }} {{ COGNOS_HOME }} -xdev -mindepth 1 -delete"

根据所有意见和建议创建全面的故障修复和故障安全实施:

# 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

我真的不喜欢rm解决方案,ansible也会提醒您使用rm。 因此,这里是如何做到这一点,而不需要rm和可靠的警告

- 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 }}"

资料来源:

先删除对应的目录,然后在创建该目录,使用的是嵌套循环
  - 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

我希望确保find命令只删除目录中的所有内容,并保持目录不变,因为在我的例子中,目录是一个文件系统。当试图删除文件系统时,系统将生成一个错误,但这不是一个好的选项。我正在使用shell选项,因为这是我目前为止找到的解决这个问题的唯一有效选项

我所做的:

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

[all:vars]
COGNOS_HOME=/tmp/cognos
find=/bin/find
并创建一个剧本:

- 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
- hosts: all
  tasks:
  - name: Ansible remove files
    shell: "{{ find }} {{ COGNOS_HOME }} -xdev -mindepth 1 -delete"

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

我已经编写了一个自定义ansible模块,用于根据多个过滤器(如年龄、时间戳、全局模式等)清理文件

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

以下是一个例子:

- cleanup_files:
  path_pattern: /tmp/*.log
  state: absent
  excludes:
    - foo*
    - bar*

如果您使用的是Ansible>=2.3(不再需要区分文件和目录),则只需使用ThorCallers Response的一个小而清晰的复制粘贴模板即可

这是我的例子

  • 安装回购
  • 安装rsyslog包
  • 止回阀
  • 删除/var/log/rsyslog中的所有文件/
  • 启动rsyslog

    - hosts: all
      tasks:
        - name: Install rsyslog-v8 yum repo
          template:
            src: files/rsyslog.repo
            dest: /etc/yum.repos.d/rsyslog.repo
    
        - name: Install rsyslog-v8 package
          yum:
            name: rsyslog
            state: latest
    
        - name: Stop rsyslog
          systemd:
            name: rsyslog
            state: stopped
    
        - name: cleann up /var/spool/rsyslog
          shell: /bin/rm -rf /var/spool/rsyslog/*
    
        - name: Start rsyslog
          systemd:
            name: rsyslog
            state: started
    

  • 这就是我想到的:

    - 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 }}" 
    
    首先,我们得到目录列表,设置

    • 文件\u键入
      任何
      ,这样我们就不会错过嵌套的目录和链接
    • 隐藏
      ,因此我们不会跳过隐藏文件
    • 另外,不要将
      递归
      设置为
      ,因为这不仅是不必要的,而且可能会增加执行时间
    然后,我们用模块遍历该列表。它的输出有点冗长,因此将帮助我们限制输出(找到此建议)


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

    - 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 }}"
    
    • 使用
    • 删除目录
    • 重新创建具有相同属性的目录

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

    不是很简单吗。。。测试工作

    例如


    以下代码适用于我:

    - 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 }}"
    

    可以工作,但没有删除以开始的文件。比如说,我也有工作。完全相同的任务,但在for
    command
    中交换了
    shell
    ,并且它工作通配符不能与command一起工作,因为它们需要一个shell来进行扩展注意,这可能会更改您的权限/所有者,除非您在创建时明确设置。这实际上是本文中最快、最可读的答案,即使不是“native Ansible”。如果你想变得更花哨,也可以使用
    rm-rf{{path}}/[!.]*{{path}}/*
    删除带前导点的文件。不需要引号。这只是我的工作代码。工件路径类似于/app/my_app/work/OP(和我自己)想要一个删除文件夹内容而不是文件夹本身的解决方案。此解决方案删除内容和文件夹本身。这是如何获得升级票的?这也会删除目录。是否有人在上面的代码失败时,工件路径为空?这感觉可能会受到这些伟大的
    rm的影响-rf/
    瞬间history@ted-k42为了安全起见,我会这样做:
    当:artifact\u path被定义并且artifact\u path!=''
    with\u fileglob
    仅在本地机器上工作
    ---
    - 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 }}"
    
    - 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 }}"