opscape

Files and directories · bash builtin

cd

Change the shell's current working directory.

cd [-L|-P] [DIRECTORY]

10 of 10 examples run in Debian 13.7 on 2026-10-31 · manual: bash(1)

cd changes the directory the shell is "in", which is where relative paths are resolved from. It has to be a shell builtin: a separate program could only change its own directory, not the shell's. For the same reason, a cd inside a script, a subshell ( ... ) or a pipeline does not move the shell you typed the command in.

With no argument, cd goes to $HOME. cd - goes back to the previous directory (stored in $OLDPWD) and prints it. Bash also keeps $PWD up to date, which is what the prompt and pwd show.

Symbolic links make "where am I" ambiguous. By default (-L, logical) bash remembers the path you typed, links included, so cd .. goes back the way you came. cd -P resolves links and lands in the real directory. To jump around and come back later, pushd and popd keep a stack of directories.

Examples

Move into a directory

cd data
pwd
output
/home/dev/demo/data

The relative path data is resolved from the current directory, /home/dev/demo, and the shell now works from /home/dev/demo/data.

Go up one level

cd src/lib
cd ..
pwd
output
/home/dev/demo/src

.. is the parent directory. cd ../.. goes up two levels.

Go to your home directory

cd
pwd
cd ~/demo/logs
pwd
output
/home/dev
/home/dev/demo/logs

cd with no argument goes to $HOME. The shell expands ~ to the same directory, so ~/demo/logs is an absolute path that works from anywhere.

Jump back to the previous directory

cd /tmp
cd ~/demo/src
cd -
cd -
output
/tmp
/home/dev/demo/src

cd - switches to $OLDPWD, the directory you were in before the last cd, and prints it. Repeating it toggles between two directories.

Changing into a directory that does not exist

cd nosuchdir
echo "exit status: $?"
output
/bin/bash: line 1: cd: nosuchdir: No such file or directory
exit status: 1

cd prints an error and returns 1, and the shell stays where it was. In scripts write cd "$dir" || exit 1, so a failed cd cannot make the following commands run in the wrong directory.

Trying to cd into a file

cd notes.txt
explain
outputexit 1
/bin/bash: line 1: cd: notes.txt: Not a directory

Only directories can be entered; a regular file gives "Not a directory" and status 1.

Directories with spaces in the name

Setup run before this example
mkdir "old reports"
cd old reports
cd "old reports" && pwd
output
/bin/bash: line 1: cd: too many arguments
/home/dev/demo/old reports

Unquoted, the shell splits old reports into two arguments and bash's cd refuses with "too many arguments". Quoting (or escaping the space as old\ reports) passes one argument.

cd in a subshell does not affect the shell

(cd logs && ls)
pwd
output
app.log
app.log.1
error.log
/home/dev/demo

The parentheses run a subshell; it changes directory, lists logs, and exits. The outer shell never moved, which makes this a tidy way to run one command elsewhere.

Shortcut directories with CDPATH

CDPATH=.:~/demo/src
cd ~
cd lib
output
/home/dev/demo/src/lib

When the name is not found relative to the current directory, cd tries each directory in CDPATH. It found lib under ~/demo/src and printed the full path to show where it went. Keep . first in CDPATH, or a local directory with the same name gets shadowed.

Common pitfalls

  • cd in a script changes the script's directory, not your shell's. To change your shell's directory, source the script or define a function.

  • Always check cd in scripts: cd "$dir" || exit. A failed cd followed by rm -rf * deletes the wrong files.

  • Exporting CDPATH makes every script's cd use it and print paths; set it in your interactive ~/.bashrc without export.

GNU vs BSD and macOS

The examples above ran the GNU/Linux version. These are the differences that matter on macOS and the BSDs (written from their documentation, not run here).

  • cd is part of the shell, not GNU or BSD userland; bash, dash and zsh all support -L, -P and cd -. zsh adds extras such as cd old new (substitute in the current path).

Options worth knowing

A selection, described in our own words. For the full list, see bash(1).

OptionWhat it does
-LFollow symlinks logically: keep the path as typed (default).
-PResolve symlinks and use the physical directory.
-eWith -P, return failure if the resulting directory cannot be determined.

Related