Repeating a description of some personal interpretation of POSIX documentation will not help the OP. There are several other questions that have explained POSIX in detail. And yet, this question.
Some basic descriptions:
A. It is a known characteristic of Linux/Unix that a file (directory) could be erased while it is being used. That is why you could keep seeing a movie after you erase it. Only when the inode of the directory entry is removed is the file really gone.
B. It also happens that the shell keeps an internal value for the actual pwd, even if the value of the environment variable $PWD is changed.
The first comment at this accepted answer of @yaegashi shows where to look (the source of pwd):
I'm correct. See the source of pwd_builtin()
. It just prints the content of the_current_working_directory. – yaegashi Jul 31 at 16:01
As shown, the shell still keeps a knowledge of the correct value of pwd ("/home/user") even starting with an odd value of PWD.
C. It should be easy to understand that the value kept by the shell could get out of sync with reality in some corner cases.
Doing a cd .
inside an erased directory seems to be one of those corner cases. It also seems that the shell adds the dot to the last known pwd on failure.
Your questions:
1. Remove the dir for PWD and execute the builtin pwd.
$ pwd
/tmp/hello
$ rmdir $PWD; pwd
/tmp/hello
The builtin pwd reports the value of pwd that the shell retains in memory.
An external /bin/pwd
will report a failure.
It is interesting to report that an pwd -P
(even if a builtin for Bash) will report a failure:
$ pwd -P
pwd: error retrieving current directory: getcwd: cannot access parent directories: No such file or directory
And, after using the builtin pwd -P
the normal pwd also fails. I believe is because the value of pwd in memory gets updated.
2. cd $PWD
I then tried to move to the directory itself and of course it was not possible (even though I was already there):
$ cd $PWD
bash: cd: /tmp/hello: No such file or directory
Any real attempt to follow the path to the directory will fail at the point in which a directory fails to be read (as when it does not exist).
3. cd .
But then I tried with cd .
, as it is supposed to be the same as cd $PWD. And this worked... somehow:
$ cd .
cd: error retrieving current directory: getcwd: cannot access parent directories: No such file or directory
The shell attempts to access the path that it knows is the pwd, and it fails. And that is what the shell reports, a failure !. No problem here.
4. New Path.
To my surprise, now I was in a new "something":
$ pwd
/tmp/hello/.
The value in memory for PWD got out-of-sync with reality and a dot (.) got added to it. As any repeat use of cd .
will add a dot.
$ cd .; pwd
/tmp/hello/./.
And, quite unexpectedly, a cd ..
will make the pwd and $PWD only ..
.
$ cd ..; pwd; echo $PWD
..
..
$ cd ..; pwd; echo $PWD
../..
../..
5. Previous PWD.
And if I tried to go to the previous directory, it of course fails:
$ cd -
bash: cd: /tmp/hello: No such file or directory
It is so because the previous value of PWD (stored in bash in OLDPWD) could not be followed.
It was (as you reported above) /tmp/hello/.
, which (being hello erased) could not be followed, and makes cd -
or cd $OLDPWD
fail.
$ echo $OLDPWD # at this point following your exact procedure.
/tmp/hello/.
6. Man pages
Funny thing also is that not even a man page works while in there:
Man pages worked for me at this point, well, in fact, at all points.
pwd
and.
determine the current path differently?, and Strange difference betweenpwd
and/bin/pwd
.