Each process has its own current working directory, which the Linux system monitors. This is one part of the information that the OS manages for each process. There is a getcwd() system call that retrieves this directory.
The $PWD environment variable reflects that getcwd() was the last shell check, but changing it does not actually change the current directory. To do this, the shell would have to call chdir() when $PWD changes, which it does not.
This is also the reason cd should be an inline shell. When you execute a subprocess, the child process gets its own working directory, so if cd were executable, then calling it to chdir() would be useless, as that would not change its parent working directory. He would change his own (short-lived) working directory. Consequently, cd is an inline shell to avoid running the subprocess.
source share