How does the shell know which directory it is in?

I am trying to figure out how the shell knows which directory you are in. I know that there is an environment variable $PWD , but when I try to change it manually, it changes what my shell displays at the prompt, but commands like ls and cd are not affected.

cd is an internal shell command, so I can understand that it can use the information stored in the memory of the shell, but ls is external and still works ls and will not give me any directory from which I was originally, regardless from what I'm doing with $PWD .

+4
source share
5 answers

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.

+12
source

The shell sets this variable, but saves it internally (therefore you cannot make cd external program, it must be inline). A shell prompt is created immediately before it is displayed every time, and you specified it with $PWD in your own, so the shell reads this.

Remember: a shell is just a program, like any other program. It can --- and --- store things in variables.


As AndiDog and John point out, unix-like systems (that is, including linux) actually support the working directory for each process through a set of system calls. However, storage is still a local process.

+9
source

The Linux kernel stores the current directory of each process. You can find it in the / proc file system (for example, "/ proc / 1 / cwd" for the init process).

The current directory can be changed using syscall chdir and obtained using getcwd .

+3
source

You (OP) start ls through your command shell and any process you run, the shell starts in the context of the current working directory. Thus, each process you run has its own variable $PWD (in a sense).

+1
source

The current directory is a property of the executable program (process), which is inherited by the processes created by this process. Changing the current directory is done by calling the operating system. The shell maps the cd operation to this system call. When you write an external program, such as ls , this program inherits the current directory.

The $PWD variable is how the shell shows you the current directory so you can use it as a variable if you need it. Changing it does not affect the real current directory of the shell itself.

+1
source

All Articles