Given
- A modern Linux/UNIX/OSX (w/
realpath
) bash
4+ (even on OSX)
Is
"$PWD" == "$(realpath .)"
Always true?
Given
realpath
)bash
4+ (even on OSX)Is
"$PWD" == "$(realpath .)"
Always true?
It's pretty easy to test that this is not always the case.
$ mkdir /tmp/realdir
$ cd /tmp/realdir
$ echo $PWD
/tmp/realdir
$ ln -s realdir /tmp/fakedir
$ cd /tmp/fakedir
$ echo $PWD
/tmp/fakedir
$ realpath .
/tmp/realdir
so no, $PWD
is not always the same as $(realpath .)
.
The bash manual indicates that the PWD
variable is set by the built-in cd
command. the default behaviour of cd is:
symbolic links are followed by default or with the -L option
This means that if you cd into a symlink the variable gets resolved relative to the symlink, not relative to the physical path. You can change this behavior for a cd
command by using the -P
option. This will cause it to report the physical directory in the PWD
variable:
$ cd -P /tmp/fakedir
$ echo $PWD
/tmp/realdir
You can change the default behavior of bash using the -P
option:
$ set -P
$ cd /tmp/fakedir
$ echo $PWD
/tmp/realdir
$ set +P
$ cd /tmp/fakedir
$ echo $PWD
/tmp/fakedir
This is of course notwithstanding the fact that you can assign anything you want to the PWD
variable after performing a cd
and it takes that value:
$ cd /tmp/fakedir
$ PWD=/i/love/cake
$ echo $PWD
/i/love/cake
but that's not really what you were asking.
It is not necessarily the case even when symbolic links are not used and PWD
is not set by the user:
vinc17@xvii:~$ mkdir my_dir
vinc17@xvii:~$ cd my_dir
vinc17@xvii:~/my_dir$ rmdir ../my_dir
vinc17@xvii:~/my_dir$ echo $PWD
/home/vinc17/my_dir
vinc17@xvii:~/my_dir$ realpath .
.: No such file or directory
Note that under zsh, ${${:-.}:A}
still gives the same answer as $PWD
(the zshexpn(1)
man page says about the A modifier: "Note that the transformation takes place even if the file or any intervening directories do not exist.").
Note that however, $PWD
contains obsolete information. Using it may be a bad idea if some other process can remove the directory. Consider the following script:
rm -rf my_dir
mkdir my_dir
cd my_dir
echo 1 > file
cat $PWD/file
rm -r ../my_dir
mkdir ../my_dir
echo 2 > ../my_dir/file
cat ./file
cat $PWD/file
rm -r ../my_dir
It will output:
1
cat: ./file: No such file or directory
2
i.e. $PWD/file
has changed.