`mv` command did not rename, but move into existing directory, from ansible

I am running an ansible task (inside a role):

- name: Rename dir
  become: yes
  shell: mv /data/files/1.6.5 /data/files/1.7.0

The intended effect is that 1.6.5 is renamed to 1.7.0

Now, on the target host, in one instance I had 1.7.0 existing:

~$ sudo ls -l /data/files/
total 1312
drwxr-x--- 2 ubuntu admin 643450 May 22 08:45 v1.6.5
drwxr-x--- 2 ubuntu admin 696320 May 25 10:19 v1.7.0

So running the above command, I had the awkward result of moving 1.6.5 INTO 1.7.0 rather than renaming it.

Why is that? It's un-intuitive. 1.6.5 was not empty, nor was 1.7.0.

Just making sure I am not missing something obvious. Or is that absolutely impossible? Did I get this from some other reason? I am just presented with the fact that I now have 1.6.5 inside 1.7.0 and doing forensics to understand why that is.


Solution 1:

The mv command will not check if a destination folder exists or not. If it doesn't exists, it will rename the source folder. Otherwise, it will just assume the pretending result is to move the source into the destination.

From the mv manpage:

   Rename SOURCE to DEST, or move SOURCE(s) to DIRECTORY.

So, if you don't want this to happen, you may add a check on your Ansible playbook to verify if the destination folder is already present, then move the folder only if it's not present:

- name: Check if the folder exists
  stat:
    path: /data/files/1.7.0
  register: dest_folder
  become: yes

- name: Rename dir
  become: yes
  shell: mv /data/files/1.6.5 /data/files/1.7.0
  when: not dest_folder.stat.exists

This way, you will avoid the undesired move into a preexisting folder.