# Replace a list of directories, but only if they are empty

**URL:** <https://forum.ansible.com/t/replace-a-list-of-directories-but-only-if-they-are-empty/23797>\
**Category:** Ansible Project\
**Created:** [February 22, 2017, 3:07pm UTC](https://forum.ansible.com/t/replace-a-list-of-directories-but-only-if-they-are-empty/23797 "2017-02-22T15:07:47Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Jesus\_Cea](https://avatars.discourse-cdn.com/v4/letter/j/82dd89/32.png) [@Jesus\_Cea](https://forum.ansible.com/u/Jesus_Cea)\
**Post date:** [February 22, 2017, 3:07pm UTC](https://forum.ansible.com/t/replace-a-list-of-directories-but-only-if-they-are-empty/23797/1 "2017-02-22T15:07:47Z")

</div>

I have spend hours trying to solve this in a clear style, with no success.

I need to replace a few directories with a symbolic link to other  
directories, but only when the first directories are empty. I have  
managed to do that with a single directory combining registered  
variables from "stat" and "find" modules, but I am not able to do it  
when I have several directories and I try to do registered variables in  
loops instead of separate tasks per directory.

This example removes directories and replaces them with symbolic links,  
but it doesn't test for emptiness first, something I need because  
ansible will happily delete a non-empty directory even with no  
"force=yes" (sadly bitten by this earlier this morning):

"""  
- name: Test directories  
&nbsp;&nbsp;stat: path=/var/spool/nullmailer/{{ item }}  
&nbsp;&nbsp;register: directories  
&nbsp;&nbsp;with\_items:  
&nbsp;&nbsp;&nbsp;&nbsp;- queue  
&nbsp;&nbsp;&nbsp;&nbsp;- tmp

- name: Delete directories, if they are actual directories  
&nbsp;&nbsp;file: path=/var/spool/nullmailer/{{ item.item }} state=absent  
&nbsp;&nbsp;when: item.stat.isdir is defined and item.stat.isdir  
&nbsp;&nbsp;with\_items: "{{ directories.results }}"

- name: Create symbolic links  
&nbsp;&nbsp;file: path=/var/spool/nullmailer/{{ item }}  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;src=/home/nullmailer-spool/{{ item }}  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;state=link  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mode=0700 owner=nullmail group=nullmail  
&nbsp;&nbsp;with\_items:  
&nbsp;&nbsp;&nbsp;&nbsp;- queue  
&nbsp;&nbsp;&nbsp;&nbsp;- tmp  
"""

---

<div class="post-metadata">

**Author:** ![Kai\_Stian\_Olstad](https://avatars.discourse-cdn.com/v4/letter/k/e19adc/32.png) [@Kai\_Stian\_Olstad](https://forum.ansible.com/u/Kai_Stian_Olstad)\
**Post date:** [February 22, 2017, 7:39pm UTC](https://forum.ansible.com/t/replace-a-list-of-directories-but-only-if-they-are-empty/23797/2 "2017-02-22T19:39:20Z")

</div>

Not tested, but you should be able test and create in one task.

- name: Create symbolic links  
&nbsp;&nbsp;&nbsp;file:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;path: /var/spool/nullmailer/{{ item.item }}  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;src: /home/nullmailer-spool/{{ item.item }}  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;state: link  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;force: yes  
&nbsp;&nbsp;&nbsp;when: item.stat.isdir is defined and item.stat.isdir and item.stat.size == 0  
&nbsp;&nbsp;&nbsp;with\_items: "{{ directories.results }}"

---

<div class="post-metadata">

**Author:** ![Jesus\_Cea](https://avatars.discourse-cdn.com/v4/letter/j/82dd89/32.png) [@Jesus\_Cea](https://forum.ansible.com/u/Jesus_Cea)\
**Post date:** [February 22, 2017, 7:59pm UTC](https://forum.ansible.com/t/replace-a-list-of-directories-but-only-if-they-are-empty/23797/3 "2017-02-22T19:59:52Z")

</div>

It doesn't work for two reasons:

1. item.stat.size meaning is nos portable between OS. In particular, an  
empty directory in linux is 4096 bytes in size. On SmartOS, size seems  
to be the number of files inside, so its value is "2" for an empty  
directory ("." and ".." are always present).

2. Ansible doesn't allow to convert a directory to a symlink directly,  
you seems to need to delete the directory first.

---

<div class="post-metadata">

**Author:** ![Kai\_Stian\_Olstad](https://avatars.discourse-cdn.com/v4/letter/k/e19adc/32.png) [@Kai\_Stian\_Olstad](https://forum.ansible.com/u/Kai_Stian_Olstad)\
**Post date:** [February 23, 2017, 6:06pm UTC](https://forum.ansible.com/t/replace-a-list-of-directories-but-only-if-they-are-empty/23797/4 "2017-02-23T18:06:52Z")

</div>

> > - name: Create symbolic links  
> > &nbsp;&nbsp;file:  
> > &nbsp;&nbsp;&nbsp;&nbsp;path: /var/spool/nullmailer/{{ item.item }}  
> > &nbsp;&nbsp;&nbsp;&nbsp;src: /home/nullmailer-spool/{{ item.item }}  
> > &nbsp;&nbsp;&nbsp;&nbsp;state: link  
> > &nbsp;&nbsp;&nbsp;&nbsp;force: yes  
> > &nbsp;&nbsp;when: item.stat.isdir is defined and item.stat.isdir and  
> > item.stat.size == 0  
> > &nbsp;&nbsp;with\_items: "{{ directories.results }}"
> 
> It doesn't work for two reasons:
> 
> 1. item.stat.size meaning is nos portable between OS. In particular, an  
> empty directory in linux is 4096 bytes in size.

On the Linux distros I use, Debian, Centos, Redhat and Ubuntu, a empty directory is 0 in stat.

> On SmartOS, size seems  
> to be the number of files inside, so its value is "2" for an empty  
> directory ("." and ".." are always present).

You can always add an exception on other OSes.  
Or you would need to find something that work on all you OSes.

> 2. Ansible doesn't allow to convert a directory to a symlink directly,  
> you seems to need to delete the directory first.

With "force: yes" it will convert a empty directory, but not a non empty directory.

So you could drop "when:" and add a "ignore\_errors: yes" instead but that doesn't look good in my opinion.
