답변 : 디렉토리 안의 파일과 폴더를 삭제하는 방법?


152

아래 코드는 웹 디렉토리에 들어가는 첫 번째 파일 만 삭제합니다. 웹 디렉토리 내부의 모든 파일과 폴더를 제거하고 웹 디렉토리를 유지하고 싶습니다. 어떻게해야합니까?

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

참고 : rm -rfcommand와 shell을 사용해 보았지만 작동하지 않습니다. 아마도 나는 그들을 잘못 사용하고 있습니다.

올바른 방향으로 도움을 주시면 감사하겠습니다.

ansible 2.1.0.0을 사용하고 있습니다


버그 인 것 같습니다.
14시 44 분

답변:


132

아래 코드는의 전체 내용을 삭제합니다 artifact_path

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

참고 : 디렉토리도 삭제됩니다.


3
따옴표는 필요하지 않습니다. 이것은 내 작업 코드입니다. artifact_path는 / app / my_app / work /와 같습니다
Mohan Kumar P

83
OP (및 나 자신)는 폴더 자체가 아니라 폴더의 내용을 삭제하는 솔루션을 원합니다. 이 솔루션은 내용과 폴더 자체를 삭제합니다.
stochastic

19
이것은 어떻게 공감대를 얻었습니까? 디렉토리도 삭제됩니다.
deppfx

17
artifact_path가 null 인 상태에서 위의 코드가 실패한 사람이 있습니까? 이것은 rm -rf /역사상 그 위대한 순간들 중 하나에 영향을 받기 쉽다고 생각합니다
ted-k42

2
@ ted-k42 안전을 위해 이와 같은 작업을 수행합니다.when: artifact_path is defined and artifact_path != ""
bmaupin

69

쉘 모듈 사용 ( 등전위 도) :

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

생성 날짜 및 소유자 / 권한에 관심이없는 경우 가장 깨끗한 솔루션 :

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

7
작동하지만로 시작하는 파일을 제거하지 않았습니다. .htaccess처럼
Abbas

쉘도 저를 위해 일했습니다. 정확히 동일한 작업이지만 교체 shell되어 command작동합니다.
SomethingOn

4
확장을 위해 쉘이 필요하므로 와일드 카드는 명령으로 작동하지 않습니다.
JamesP

1
생성하는 동안 명시 적으로 설정하지 않으면 권한 / 소유자가 변경 될 수 있습니다.
NeverEndingQueue

사용 쉘은 당신이 상태가 대신 쉘 RM의 부재 =와 파일 모듈을 사용하여 경고를 얻을 것이다. 이를 피하려면 args를
Rodrigo

60

디렉토리 (기본적으로 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 = Trueansible.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
      }}

6
첫 번째 작업은 내가 본 가장 우아한 솔루션입니다. 추가 기능을 오래 실행해야한다는 의견이 있습니다.state=empty
William Turrell

24

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

출처 : http://www.mydailytutorials.com/ansible-delete-multiple-files-directories-ansible/


질문에 대한 최고의 솔루션!
Vsegar

18

아래 명령을 시도하면 작동합니다.

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

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

3
올바르게와 마지막 줄을 탈출 놓친 {{}} 얻을 수with_items: "{{ contents.stdout_lines }}"
발레 Crini

ls바꿈과 같은 특수 문자를 사용하여 파일 이름을 올바르게 인쇄하지 않으므로 '출력 을 사용 하여 파일 이름을 얻는 것은 위험합니다 .
bfontaine

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

register대한 내용 이 누락 된 것 같습니다 plugin_dir_deleted.
밥 보크

이것을 지적 해 주셔서 감사합니다. 나는이 코드 조각이 내 플레이 북 중 하나 꺼내했고, 명명의 관점에서 더 일반적인했지만 두 변수의 이름을 대체하는 것을 잊지
마르쿠스

1
좋은 점이지만 마지막 작업의 상태를 "present"가 아닌 "directory"로 설정해야한다고 생각합니다.
Andrew Allaire

1
통계 결과를 사용하여 권한을 유지해야합니다 : pw_name의 소유자, gr_name의 그룹 및 mode의 모드.
DylanYoung

시도 owner: dir_to_delete.stat.pw_name, group: dir_to_delete.stat.gr_name mode: dir_to_delete.stat.mode했지만 현재 Ansible 버전으로 실패합니다 :(
Markus

3

파일 글로브를 사용하면 작동합니다. 게시 한 코드에 구문 오류가 있습니다. 나는 이것이 작동하도록 수정하고 테스트했다.

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

7
with_fileglob원격 컴퓨터가 아닌 로컬 컴퓨터에서만 작동합니다. 사실이 아닙니까?
Stepan Vavra

True .. with_fileglob는 로컬 전용입니다.
Deepali Mittal

또한 디렉토리를 삭제하지 않고 파일 만 삭제합니다.
vikas027

2

Ansible은 여전히 https://github.com/ansible/ansible-modules-core/issues/902 를 구현하기 위해 논쟁 중이지만state = empty

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

그러나 동기화를 사용하면 파일을 삭제와 함께 올바르게 동기화 할 수 있어야합니다.


2

그것이 내가 생각해 낸 것입니다.

- 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중첩 된 디렉토리와 링크를 놓치지 않을 것입니다.
  • hidden에는 yes, 그래서 우리는 숨겨진 파일을 생략하지 않는다
  • 또한, 설정하지 마십시오 recurseyes그것을뿐만 아니라 필요하지만, 실행 시간을 증가시킬 수 있기 때문에.

그런 다음 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.


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

1

나이, 타임 스탬프, 글로브 패턴 등과 같은 여러 필터를 기반으로 파일을 정리하기 위해 사용자 정의 가능한 모듈을 작성했습니다.

또한 이전 버전과 호환됩니다. 여기 에서 찾을 수 있습니다 .

예를 들면 다음과 같습니다.

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

0

find 명령은 디렉토리 내부의 모든 항목 만 삭제하고 디렉토리는 파일 시스템이므로 디렉토리를 그대로 유지하고 싶습니다. 파일 시스템을 삭제하려고 할 때 시스템에서 오류가 발생하지만 좋은 옵션은 아닙니다. 쉘 옵션을 사용하고 있습니다.이 질문에 대해 지금까지 찾은 유일한 작업 옵션이기 때문입니다.

제가 한:

호스트 파일을 편집하여 일부 변수를 넣으십시오.

[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"옵션은 현재 디렉토리를 건드리지 않도록합니다.


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

-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


1
작동하지만 쉘 모듈을 사용하는 것이 항상 최후의 수단이어야합니다.
Chris

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

-4

이것이 나의 예입니다.

  1. 저장소 설치
  2. rsyslog 패키지 설치
  3. rsyslog 중지
  4. / var / log / rsyslog / 내부의 모든 파일을 삭제하십시오.
  5. 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
    

-6

아래는 나를 위해 일했습니다.

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

디렉토리가 존재하는지 확인합니다. 그것이 아니라면 그것을보고하지 않을 것입니다.
Chris
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.