Why is cd not a program?

I’ve always wondered why cd isn’t a program, but never managed to find the answer.

Anyone know why this is the case?

Asked By: AkshaiShah

||

The cd command modifies the “current working directory”, right?

“current working directory” is a property that is unique to each process.

So, if cd was a program it would work like this:

  1. cd foo
  2. the cd process starts
  3. the cd process changes the directory for the cd process
  4. the cd process exits
  5. your shell still has the same state, including current working directory, that it did before you started.
Answered By: Daniel Pittman

From the Bash introduction (What is a shell?):

Shells also provide a small set of built-in commands (builtins)
implementing functionality impossible or inconvenient to obtain via
separate utilities. For example, cd, break, continue, and
exec) cannot be implemented outside of the shell because they
directly manipulate the shell itself. The history, getopts,
kill, or pwd builtins, among others, could be implemented in
separate utilities, but they are more convenient to use as builtin
commands. All of the shell builtins are described in subsequent
sections.

Answered By: cjc

cd in addition to being a shell builtin, is actually also a program on POSIX compliant OSes. They must provide independent executables for regular utilities, like cd. This is for example the case with Solaris, AIX, HP-UX and OS X.

Obviously, a builtin cd is still mandatory as its external implementation doesn’t change the current shell directory. However, the latter can still be useful. Here is an example showing how POSIX envision how this cd command could be used:

find . -type d -exec cd {} ;

On a POSIX system, this oneliner will report an error message for all directories you aren’t allowed to cd in. On most Gnu/Linux distributions, it fails with that error message though:

find: `cd': No such file or directory

And here is the answer to your question, “Why is cd not a program?” by one of the original Unix co-author. On a very early Unix implementation, cd (spelled chdir at that time) was an external program. It just stopped working unexpectedly after fork was first implemented.

Quoting Dennis Ritchie:

In the midst of our jubilation, it was discovered that the chdir (change current directory) command had stopped working. There was much reading of code and anxious introspection about how the addition of fork could have broken the chdir call. Finally the truth dawned: in the old system chdir was an ordinary command; it adjusted the current directory of the (unique) process attached to the terminal. Under the new system, the chdir command correctly changed the current directory of the process created to execute it, but this process promptly terminated and had no effect whatsoever on its parent shell! It was necessary to make chdir a special command, executed internally within the shell. It turns out that several command-like functions have the same property, for example login.

Source: Dennis M. Ritchie, “The Evolution of the Unix Time-sharing System”, AT&T Bell Laboratories Technical Journal 63(6), Part 2, Oct. 1984, pp.1577–93

Unix Version 1 (March 1971) chdir manual page states:

Because a new process is created to execute each command,
chdir would be ineffective if it were written as a normal
command. It is therefore recognized and executed by the
Shell.

Answered By: jlliagre

cd is a shell built-in command. As easy as is. The man cd says it all. the cd command changes the working directory for all interpreters and (in a threaded environment) all threads.

Answered By: user18925

For April Fool’s this year, I wrote a standalone version of cd.

No one got the joke. Sigh.

Anyone who isn’t sure that cd must be built into the shell should download it, build it, and try it.

Read its man page, too. 🙂

Answered By: Warren Young

I think one thing missing in people answer is that current directory is a environment variable that each program can change. If you use ‘export’ command to see your current environment variables list, you will have:

declare -x PWD="/home/erfan"

in your results.
Thus by ‘cd’ command we just want to modify this internal variable.
I think if we try, we can chage the PWD variable of any pty in shell, of course.
Like:

cder    #change current PTY $PWD variable

But I think there s no need in normal cases.
In another word, we take help from bash(or any shell) to modify its internal variable defined.

Answered By: Erfankam

The cd command in shell cannot be a separate process because in Unix there is no mechanism to change the current working directory of a different process (not even the parent process).

If cd was a different process then it would have to change the current working directory of its parent (shell) which is not possible in Unix.
Instead cd is a special built in command. The shell calls functions like chdir() and fchdir() changing its own current working directory.

Note : the kernel stores the inode number of the current working directory for every process. The child process inherits it’s cwd from its parent.

Answered By: saurav1405