Ansible: डायरेक्टरी के अंदर फाइल और फोल्डर को कैसे डिलीट करें?


152

नीचे दिया गया कोड केवल पहली फ़ाइल को हटाता है जो वेब dir के अंदर मिलती है। मैं वेब निर्देशिका के अंदर सभी फ़ाइलों और फ़ोल्डरों को हटाना चाहता हूं और वेब निर्देशिका को बनाए रखना चाहता हूं। मैं उसे कैसे कर सकता हूँ?

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

नोट: मैंने rm -rfकमांड और शेल का उपयोग करने की कोशिश की है , लेकिन वे काम नहीं करते हैं। शायद मैं उनका गलत इस्तेमाल कर रहा हूं।

सही दिशा में किसी भी मदद की सराहना की जाएगी।

मैं 2.1.0.0 ansible का उपयोग कर रहा हूं


बग जैसा दिखता है।
छत

जवाबों:


132

नीचे दिए गए कोड से संपूर्ण सामग्री हट जाएगी artifact_path

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

नोट : यह निर्देशिका को भी हटा देगा।


3
उद्धरण आवश्यक नहीं हैं। यह केवल मेरा काम करने वाला कोड है। विरूपण साक्ष्य_पथ / एप / my_app / कार्य /
मोहन कुमार पी।

83
ओपी (और खुद) एक समाधान चाहते हैं जो फ़ोल्डर की सामग्री को हटा देगा लेकिन फ़ोल्डर खुद नहीं। यह समाधान सामग्री और फ़ोल्डर को स्वयं हटा देता है।
स्टोकेस्टिक

19
यह एक उत्थान कैसे हुआ? यह निर्देशिका को भी हटा देता है।
डेपफैक्स

17
क्या किसी को भी उन पर उपरोक्त कोड विफल रहा है जिसके साथ विरूपण साक्ष्य_पथ शून्य है? ऐसा लगता है कि यह rm -rf /इतिहास के उन महान क्षणों में से एक के लिए अतिसंवेदनशील हो सकता है
ted-k42

2
@ ted-k42 मैं कुछ इस तरह से करना चाहूंगा कि यह सुरक्षित रहे:when: artifact_path is defined and artifact_path != ""
बामुपरिन

69

शेल मॉड्यूल का उपयोग करना ( उदासीन भी):

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

यदि आप निर्माण तिथि और स्वामी / अनुमतियों के बारे में परवाह नहीं करते हैं तो सबसे बेहतर समाधान:

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

7
काम करता है, लेकिन शुरू होने वाली फ़ाइलों को नहीं हटाता है। जैसे .htaccess
अब्बास

शेल ने मेरे लिए भी काम किया। सटीक एक ही कार्य लेकिन इसमें अदला-बदली shellहुई commandऔर यह काम करता है
समथिंग

4
वाइल्डकार्ड कमांड के साथ काम नहीं करेंगे क्योंकि उन्हें विस्तार के लिए एक शेल की आवश्यकता होती है
जेम्स 23

1
ध्यान दें कि यह आपकी अनुमति / स्वामी को तब तक बदल सकता है जब तक कि आप निर्माण क्षण के दौरान स्पष्ट रूप से सेट न करें।
NeverEndingQueue

का प्रयोग खोल आप फ़ाइल मॉड्यूल का उपयोग कर राज्य खोल rm के बजाय अनुपस्थित = साथ की एक चेतावनी मिल जाएगा। इससे बचने के लिए बस आर्गन
रोड्रिगो

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

6
पहला कार्य सबसे सुरुचिपूर्ण समाधान मैंने देखा है। टिप्पणी कहीं और ध्यान दें कि जोड़ने के लिए एक लंबे समय से चल रही सुविधा अनुरोध हैstate=empty
विलियम टरेल

24

मैं वास्तव में आरएम समाधान पसंद नहीं था, यह भी 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/


अभी तक सवाल का सबसे अच्छा समाधान !!
वेसर

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
अच्छा सामान है, लेकिन मुझे लगता है कि अंतिम कार्य में राज्य को "वर्तमान" के बजाय "निर्देशिका" पर सेट करने की आवश्यकता है।
एंड्रयू अलाइरे

1
अनुमतियों को संरक्षित करने के लिए आपको अपने स्टेट परिणाम का उपयोग करना चाहिए: pw_name से स्वामी, gr_name से समूह, और मोड से मोड।
DylanYoung

की कोशिश की, owner: dir_to_delete.stat.pw_name, group: dir_to_delete.stat.gr_name mode: dir_to_delete.stat.modeलेकिन यह मेरे वर्तमान Ansible संस्करण के साथ मुझ पर विफल रहता है :(
मार्कस

3

फ़ाइल ग्लोब का उपयोग करना भी काम करेगा। आपके द्वारा पोस्ट किए गए कोड में कुछ सिंटैक्स त्रुटि है। मैंने संशोधित किया है और परीक्षण किया है कि यह काम करना चाहिए।

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

7
with_fileglobकेवल स्थानीय मशीन पर काम करता है, रिमोट नहीं; क्या यह सच नहीं है?
Stepan Vavra

सच .. with_fileglob केवल स्थानीय के लिए है
दीपाली मित्तल

इसके अलावा, यह निर्देशिकाओं को हटाता नहीं है, बस फाइलें हटा दी जाती हैं।
vikas027 23

2

जबकि अन्सिबल अभी भी 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_typeकरने के लिए anyहै, तो हम करेंगे याद आती है नेस्टेड नहीं निर्देशिका और लिंक
  • hiddenकरने के लिए yes, तो हम छिपा फ़ाइलों को ना छोड़ें
  • इसके अलावा, सेट न recurseकरें yes, क्योंकि यह न केवल अनावश्यक है, बल्कि निष्पादन समय भी बढ़ा सकता है।

फिर, हम 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हैं।


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

मैंने कई फिल्टर जैसे उम्र, टाइमस्टैम्प, ग्लोब पैटर्न आदि के आधार पर फाइलों को साफ करने के लिए एक कस्टम ansible मॉड्यूल लिखा है।

यह पुराने पुराने संस्करणों के साथ भी संगत है। यह यहाँ पाया जा सकता है

यहाँ एक उदाहरण है:

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

0

मैं यह सुनिश्चित करना चाहता हूं कि खोज कमांड केवल निर्देशिका के अंदर सब कुछ हटा देती है और निर्देशिका को बरकरार रखती है क्योंकि मेरे मामले में निर्देशिका एक फाइल सिस्टम है। फ़ाइल सिस्टम को हटाने का प्रयास करते समय सिस्टम एक त्रुटि उत्पन्न करेगा लेकिन यह एक अच्छा विकल्प नहीं है। Iam शेल विकल्प का उपयोग करते हुए क्योंकि मैं इस प्रश्न के लिए अब तक पाया गया एकमात्र कार्य विकल्प हूं।

मैंने क्या किया:

कुछ चर में डालने के लिए मेजबान फ़ाइल को संपादित करें:

[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 का उपयोग कर रहे हैं, तो थोरसुमोनर्स की बस एक छोटी सी क्लीनर कॉपी और पेस्ट टेम्प्लेट का उत्तर दें।

- 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

मान लें कि आप हमेशा लिनक्स में हैं, तो 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
यह काम कर सकता है लेकिन शेल मॉड्यूल का उपयोग हमेशा एक अंतिम उपाय होना चाहिए।
क्रिस

-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

यह सिर्फ पुष्टि करेगा कि निर्देशिका मौजूद है। अगर यह नहीं करता है तो इसे बनाएगा, लेकिन रिपोर्ट के अलावा कुछ नहीं करता है अगर यह करता है तो ठीक है।
क्रिस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.