I have two shells open. The first is in directory A. In the second, I remove directory A, and then recreate it. When I go back to the first shell, and type ls
, the output is:
ls: cannot open directory .: Stale file handle
Why? I thought the first shell (the one that remained open inside a non-existent directory) would "freeze" while waiting for the next command, and wouldn't have "realized" that the directory was deleted and recreated. Does the shell hold a "deeper" reference to its current working directory other than the string $PWD
?
Best Answer
A directory (like any file) is not defined by its name. Think of the name as the directory's address. When you move the directory, it's still the same directory, just like if you move to a different house, you're still the same person. If you remove a directory and create a new one by the same name, it's a new directory, just like someone who moves into the house where you used to live isn't you.
Each process has a working directory. The
cd
command in the shell changes the shell's current working directory. Thepwd
command prints the¹ path to the current working directory.When you removed the directory A, what this did was to remove the entry for A in its parent directory. The directory A itself remained in the filesystem, but in a detached state, with no name. It was not deleted yet because it was in use by a process, namely the first shell. When you changed the directory in the first shell, the directory was finally deleted. The same thing happens when a file is deleted while a process still has it open: the file's directory entry is removed immediately, and the file itself is removed when it stops being in use.
Similarly, observe what happens when you move directories around.
In another shell:
In the first shell:
The file
1
is in the directory that was originally calledone
and is now calledtwo
. The file2
is in the directory that was originally calledtwo
and is now calledone
.¹ More precisely, a path, which may not be unique if symbolic links or other subtleties are involved.