ZetCode

Linux cd Command

last modified October 23, 2026

The cd (change directory) command changes the current working directory of the shell. Relative paths, many commands, and new files all use the current directory, so cd is one of the most frequently used commands on the command line.

cd is a shell builtin, not a separate program, because a child process cannot change the working directory of its parent. The pwd command prints the current directory. The examples use Bash and the home directory /home/jano.

Absolute paths

An absolute path starts at the root directory / and works from any location.

cd /usr/share/doc

We print the current directory with pwd before and after the change. A new shell starts in the home directory.

$ pwd
/home/jano
$ cd /usr/share/doc
$ pwd
/usr/share/doc

Relative paths

A path without a leading slash is relative to the current directory.

cd ~/projects
cd website/css

From /home/jano/projects, the relative path website/css leads to /home/jano/projects/website/css. Tab completion helps to type directory names quickly and correctly.

$ cd ~/projects
$ cd website/css
$ pwd
/home/jano/projects/website/css

Parent directories

The special name .. refers to the parent directory, and . to the current one.

cd ..
cd ../..
cd ./projects/api

Each .. moves one level up, so ../.. moves two levels. Paths can mix .. with directory names, for example cd ../api to move to a sibling directory.

$ cd ..
$ pwd
/home/jano/projects/website
$ cd ../..
$ pwd
/home/jano
$ cd ./projects/api
$ pwd
/home/jano/projects/api

The home directory

cd without arguments returns to the home directory, which is stored in the HOME variable. The tilde ~ expands to the home directory as well.

cd
cd ~/projects
cd ~root

The form ~user expands to the home directory of another user; here we are not allowed to enter the home directory of root, so we stay where we are.

$ cd
$ pwd
/home/jano
$ cd ~/projects
$ pwd
/home/jano/projects
$ cd ~root
bash: cd: /root: Permission denied
$ pwd
/home/jano/projects
$ echo $HOME
/home/jano

The previous directory

cd - switches to the previous directory and prints its name.

cd /etc
cd /var/log
cd -
cd -

Repeating cd - toggles between two directories. The previous directory is stored in the OLDPWD variable.

$ cd /etc
$ cd /var/log
$ cd -
/etc
$ cd -
/var/log
$ echo $OLDPWD
/etc

Names with spaces

The shell splits arguments at spaces, so directory names containing spaces must be quoted or escaped.

cd ~/"My Documents"
cd ~/My\ Documents

Without quotes, cd receives two arguments and fails. The tilde must stay outside the quotes, because it is not expanded inside them; the variable form cd "$HOME/My Documents" works too.

$ cd ~/My Documents
bash: cd: too many arguments
$ cd ~/"My Documents" && pwd
/home/jano/My Documents
$ cd ~/My\ Documents && pwd
/home/jano/My Documents

Errors

cd fails when the target does not exist, is not a directory, or cannot be entered.

cd /nonexistent
cd ~/notes.txt
cd ~/private || echo "cd failed with status $?"

Entering a directory requires the execute permission on it; our private directory has no permissions at all. A failed cd returns a non-zero exit status and leaves the current directory unchanged.

$ cd /nonexistent
bash: cd: /nonexistent: No such file or directory
$ cd ~/notes.txt
bash: cd: /home/jano/notes.txt: Not a directory
$ cd ~/private || echo "cd failed with status $?"
bash: cd: /home/jano/private: Permission denied
cd failed with status 1

CDPATH

The CDPATH variable lists directories that cd searches for relative names, similar to how PATH works for commands.

CDPATH=.:~/projects
cd api
cd website

From /tmp, cd api finds the directory in ~/projects. When a directory is found through CDPATH, cd prints the new path. Keep . as the first entry so that subdirectories of the current directory take precedence, and do not export the variable, as it can confuse scripts.

$ cd /tmp
$ CDPATH=.:~/projects
$ cd api
/home/jano/projects/api
$ cd website
/home/jano/projects/website

The directory stack

The pushd and popd builtins change the directory while remembering previous locations on a stack.

pushd /etc
pushd /var/log
dirs -v
popd
popd

pushd changes to a directory and pushes it onto the stack; popd removes the top entry and returns to the next one. Both print the stack, with the home directory abbreviated as ~. dirs -v shows the stack with indexes, and cd ~2 jumps to the entry with index 2.

$ cd ~
$ pushd /etc
/etc ~
$ pushd /var/log
/var/log /etc ~
$ dirs -v
 0  /var/log
 1  /etc
 2  ~
$ popd
/etc ~
$ popd
~
$ pwd
/home/jano

Combining cd with other commands

In scripts, cd should be checked before running commands that depend on the directory.

(cd /tmp && pwd)
cd /etc && ls -d ssh
cd /missing && rm -f *.tmp

Commands in parentheses run in a subshell, so the directory change does not affect the current shell. With &&, the second command runs only if cd succeeds. This matters: had we used ; instead, rm would have deleted files in the current directory after the failed cd.

$ cd ~
$ (cd /tmp && pwd)
/tmp
$ pwd
/home/jano
$ cd /etc && ls -d ssh
ssh
$ cd /missing && rm -f *.tmp
bash: cd: /missing: No such file or directory
$ pwd
/etc

Symbolic links

By default, cd follows symbolic links logically and remembers the path as typed. The -P option uses the physical path.

cd ~/site
pwd
pwd -P
cd -P ~/site

The link ~/site points to ~/projects/website. pwd shows the logical path, while pwd -P resolves the link. With cd -P, the physical path becomes the current directory. In logical mode, cd .. from a linked directory returns to the directory containing the link.

$ cd ~/site
$ pwd
/home/jano/site
$ pwd -P
/home/jano/projects/website
$ cd -P ~/site
$ pwd
/home/jano/projects/website

Why cd is a builtin

A script runs in a separate process, so a cd inside it does not change the directory of the calling shell.

type cd
bash goto.sh

The script changes to /tmp, but after it finishes, we are still in the home directory. To change the directory of the current shell, the script must be sourced with source goto.sh or . goto.sh, or the commands must be put in a shell function.

$ type cd
cd is a shell builtin
$ cat goto.sh
cd /tmp
$ bash goto.sh
$ pwd
/home/jano

Best practices for cd

Source

Bash manual: Bourne shell builtins

In this article, we have used the cd command with absolute and relative paths, the home and previous directories, CDPATH, the directory stack, and symbolic links.

Author

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.

List all Linux tutorials.