Basically, in Python or bash I can rename a directory to a different name from within that directory : at that point, from within the directory, the old name still shows, but the rename has in fact already taken place.
On macos with APFS, this came about in a Python script I was writing to rename directories as per a specific naming convention I use and I noticed this behavior.
I am posting this as posix/shell/macos as I half expect this to happen as well under Linux and I got the same general behavior out of the zshell.
Let's say I have a directory, foo
:
(venv) jluc@test$ tree
.
└── foo
I rename it to bar with mv foo bar
(venv) jluc@test$ tree
.
└── bar
But now, let's cd into that directory and perform the rename there.
$cd bar
$pwd
/Users/jluc/kds2/wk/explore/test/bar
$ mv ../bar ../zoom
$ pwd
/Users/jluc/kds2/wk/explore/test/bar 👈 still the old name
So, now, within bar
, I've renamed it to zoom
. It did not error out. Locally, a pwd
shows that I am still in the same directory. I can do an ls
and I am not in a invalid directory which some commands can sometime put me in.
However, a tree one level up tells a different story.
(venv) jluc@bar$ tree ..
..
└── zoom 👈 but here I see the new name
and cd to the current directory fails
cd `pwd`
-bash: cd: /Users/jluc/kds2/wk/explore/test/bar: No such file or directory
What, in the name of Schrodinger's 😺, is going on? Does the inode scheme underlying the file system, APFS, provide this? Would different filesystems, like ext4 for example also exhibit the same behavior?
Update: if I have a separate text file in my testing directory, I can cat
the contents of the file before and after the rename locally, so it's not just the shell - the file system collaborates as well. The current directory is still valid and operational (which would fit with @that other guy's answer).
There are two things at play:
#1 means that for the most part, you can delete or move a file/dir that's still in use, and the using process can continue using it until it's done. #2 means that the shell's pwd
will just return the old name (though external /bin/pwd
which has to requery will fail).