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

时间:2016-07-05 10:12:09

标签: ansible delete-file delete-directory

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

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

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

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

我使用的是ansible 2.1.0.0

20 个答案:

答案 0 :(得分:121)

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

- name: Clean artifact path
  file:
    state: absent
    path: "{{ artifact_path }}/"

注意:这也会删除目录。

答案 1 :(得分:57)

使用shell模块( idempotent ):

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

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

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

答案 2 :(得分:37)

删除目录(基本上是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

如果您无法删除整个目录并重新创建它,则可以扫描它以查找文件,(和目录),然后逐个删除它们。这需要一段时间。您可能希望确保在ansible.cfg上有[ssh_connection]\npipelining = 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
      }}

答案 3 :(得分:17)

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

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

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

答案 4 :(得分:15)

我真的不喜欢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 }}"

来源:Result

答案 5 :(得分:5)

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

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

答案 6 :(得分:4)

从所有评论和建议中创建了一个全面的,经过全面修复的安全实施方案:

# 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

答案 7 :(得分:3)

以下代码对我有用:

df.columns = pd.MultiIndex.from_arrays([col_l1,df.columns],names=['L0','L1'])

L0 col0_L0 col1_L0 col2_L0
L1 col0_L1 col1_L1 col2_L1
0       14      58      52
1       92      21      16
2       39      86      93
print(df.columns)

 MultiIndex([('col0_L0', 'col0_L1'),
            ('col1_L0', 'col1_L1'),
            ('col2_L0', 'col2_L1')],
           names=['L0', 'L1'])

答案 8 :(得分:2)

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

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

答案 9 :(得分:2)

对此有一个issue open

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

以下是一个示例剧本:

- 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

答案 10 :(得分:1)

我想确保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”选项可确保不会触摸当前目录。

答案 11 :(得分:1)

这就是我想出的:

- 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_typeany,因此我们不会错过嵌套的目录和链接
  • hiddenyes,因此我们不会跳过隐藏文件
  • 也不要将recurse设置为yes,因为这不仅不必要,而且会增加执行时间。

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


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

- 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

答案 12 :(得分:0)

假设您总是在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

下的文件/文件夹/隐藏

答案 13 :(得分:0)

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

答案 14 :(得分:0)

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

它也与旧版本兼容。可以找到here

这里是一个例子:

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

答案 15 :(得分: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

答案 16 :(得分:0)

以下是波纹管

- hosts: all
  tasks:
    - name: Empty remote directory
      file:
        path: /home/felipe/files
        state: absent
      become: yes

    - name: Create
      file:
        path: /home/felipe/files
        state: directory
        owner: jboss
        group: jboss
        mode: u=rwx,g=rx,o=rx
      become: yes

答案 17 :(得分:0)

不是那么简单...经过测试工作..

例如

if (bodyDeclaration.isMethodDeclaration()) {
    MethodDeclaration method = (MethodDeclaration) bodyDeclaration;

    // [public, static]
    NodeList<Modifier> modifiers = method.getModifiers();
    // int
    Type type = method.getType();
    // calculate
    SimpleName name = method.getName();
    // [int a, int b]
    NodeList<Parameter> parameters = method.getParameters();
}

答案 18 :(得分:-4)

以下为我工作,

    [DllImport("user32.dll")]
    private static extern int GetWindowLong(IntPtr hWnd, int nIndex);
    [DllImport("user32.dll")]
    private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
    private const int GWL_STYLE = -16;
    private const int WS_MAXIMIZEBOX = 0x10000;

    private void Window_OnSourceInitialized(object sender, EventArgs e)
    {
            var hwnd = new WindowInteropHelper((Window)sender).Handle;
            var value = GetWindowLong(hwnd, GWL_STYLE);
            SetWindowLong(hwnd, GWL_STYLE, (int)(value & ~WS_MAXIMIZEBOX));
    }

答案 19 :(得分:-4)

这是我的例子。

  1. 安装存储库
  2. 安装rsyslog软件包
  3. 停止rsyslog
  4. 删除/ var / log / rsyslog /
  5. 中的所有文件
  6. 启动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