1

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).

JL Peyret
  • 10,917
  • 2
  • 54
  • 73

1 Answers1

3

There are two things at play:

  1. On Unix, any handle to an open file or directory will generally be unaffected by renames and deletions.
  2. The shell remembers the directory you're in, it doesn't re-query every time.

#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).

that other guy
  • 116,971
  • 11
  • 170
  • 194
  • So, wrt #1, would you consider this to be a kernel-level behavior? I can also `cat` the contents of a file in my renamed directory, so it goes beyond just *an open file*. – JL Peyret Nov 11 '19 at 22:40
  • Yes, this is definitely kernel level behavior. Due to this behavior, `.` will still reference the same inode after a move, so you can still `cat` files relative to it. – that other guy Nov 11 '19 at 23:05