Step 1 of 5 · Reading · ~3 min
Read
Built-ins & Variables
Built-in Commands: cd, pwd, exit
After this lesson your shell changes directory for real: cd updates the shell's own working directory, cd - goes back and says where it went, pwd and $PWD agree, a failed cd leaves everything as it was, and exit stops the shell with a status. The directories are virtual here, so you can test every case without touching a disk.
Why cd cannot be a program
Every other command you type is run by forking a child and calling exec in it. Try that with cd:
shell (cwd /home/user)
|-- fork --> child: chdir("/tmp"), then exits
shell (cwd still /home/user)
A working directory belongs to a process. The child changes its own and dies; the shell's is untouched. The same holds for exit, for variable assignment and for exec. They must run inside the shell process, and that is the definition of a built-in. The shell checks its built-in table before it forks.
State a shell keeps
PWD, the current directory, as an absolute path.OLDPWD, the directory before the last successfulcd. It starts unset.$?, the exit status of the last command: 0 for success, non-zero for failure, 127 for a command not found.
What cd does
- No argument means
HOME. A leading~meansHOME, so~/docsisHOME/docs. - The argument
-meansOLDPWDand, as the one case wherecdprints, writes the new directory. IfOLDPWDis unset, the error iscd: OLDPWD not set. - A relative path is joined to
PWD. Then the path is normalized textually: repeated slashes collapse,.disappears, and..removes the previous component (at the root it stays at the root). This is the logicalcd -Lbehaviour that shells default to. - If the result is not a directory, print
cd: <argument as typed>: No such file or directory, set status 1 and change nothing, includingOLDPWD. - On success set
OLDPWDto the oldPWD,PWDto the new path, and status 0.
More than one argument is cd: too many arguments, status 1.
exit
exit stops the shell. With a number it uses that number modulo 256, so exit 256 is 0 and exit -1 is 255; with no argument it uses the status of the last command. A non-number prints exit: <arg>: numeric argument required and the status is 2. Too many arguments prints exit: too many arguments and, unusually, does not exit.
A worked trace
Start in the home directory. cd /tmp sets OLDPWD to the home directory. cd - prints the home directory and swaps the two. Another cd - prints /tmp. If a cd /missing came between them, nothing would change, so both swaps would still work.
Common mistakes
- Printing the directory after every
cd. Onlycd -prints. - Updating
OLDPWDbefore you know thecdwill succeed. - Letting
..climb above the root, or leaving//or/./in the stored path. - Reporting the normalized path in the error message instead of the argument as typed.
Your exercise
The starter keeps the directory table, the path normalizer and the line loop, and handles the setup lines that create directories. You write the command dispatcher. The most likely mistake is changing OLDPWD on a failed cd.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…