cd Command Explained
cd changes your current location in the filesystem. It is one of the first commands anyone learns, and one of the few genuinely special ones: unlike almost everything else you type into a terminal, cd cannot be an ordinary external program.
Basic usage
cd /var/log # absolute path: always goes to the same place
cd Documents # relative path: goes into Documents from wherever you are
cd .. # up one directory level
cd ../.. # up two directory levels
cd # no argument: goes straight to your home directory
cd ~ # explicitly your home directory, same as plain cd
Absolute vs relative paths
# Absolute: starts with /, always the same regardless of current location
cd /home/colton/projects/linuxdork
# Relative: interpreted from wherever you currently are
cd projects/linuxdork # works only if you start from /home/colton
cd ../sibling-project # goes up one level, then into sibling-project
An absolute path is unambiguous no matter where you start. A relative path depends entirely on your current working directory, which is why confirming your location with pwd before a relative cd in a script or unfamiliar terminal session is a reasonable habit.
Useful shortcuts
cd -
# /home/colton/Documents
cd - jumps back to whatever directory you were in immediately before your last cd, and prints that path so you know where you landed. This is genuinely useful for bouncing between two locations repeatedly, for example switching between a project’s source directory and its configuration directory, without retyping either full path.
cd ~ # your own home directory
cd ~alice # another user's home directory (if you have access)
cd ~- # your previous directory (same effect as cd -)
Going up multiple levels at once
cd .. # up one level
cd ../.. # up two levels
cd ../../.. # up three levels
Chaining ../ segments inside a single cd command is more efficient than running cd .. repeatedly, and makes the intent clearer in scripts.
pushd, popd, and the directory stack
pushd /var/log
# now in /var/log, previous directory pushed onto the stack
pushd /etc/nginx
# now in /etc/nginx, /var/log still on the stack beneath it
popd
# back to /var/log
dirs -v
# shows the full stack with index numbers
For workflows that bounce between more than two directories, pushd and popd maintain a full stack rather than just the single “previous directory” that cd - tracks. dirs -v shows the entire stack with index numbers, and you can jump directly to any entry with cd ~N referencing that index.
Why cd has to be a shell builtin
This is worth understanding because it explains a category of “why doesn’t this work” confusion for people newer to Linux. Every external command you run, ls, grep, cp, launches in its own separate child process. A child process has its own working directory, and changing it only affects that child process, not the shell that launched it. When the child process exits, whatever directory changes it made inside itself simply disappear along with it.
# This would NOT work as an external program:
# a hypothetical /bin/cd running as a child process could change
# ITS OWN working directory, then exit, and your shell would be
# completely unaffected, still sitting in the original directory
# This is why cd must be built directly into the shell:
type cd
# cd is a shell builtin
Because cd needs to modify the state of your actual, currently running shell session rather than some short-lived child process, it has to be implemented as a built-in command inside the shell itself (bash, zsh, and so on), not as a standalone program living somewhere in /bin or /usr/bin.
Common patterns in scripts
#!/bin/bash
# Go somewhere, do work, and always return, even on error
pushd /tmp/workdir > /dev/null
# ... commands that assume /tmp/workdir as the working directory ...
popd > /dev/null
# Or the simpler, common subshell pattern
(cd /tmp/workdir && tar -czf archive.tar.gz .)
# the parentheses run cd in a subshell, so the CALLING script's
# own working directory is completely unaffected afterward
The subshell pattern, wrapping cd and the following commands in parentheses, is a common trick to temporarily change directory for a handful of commands without permanently affecting the script’s own working directory once that subshell finishes.
Frequently Asked Questions
What does the cd command do?
cd changes your shell session’s current working directory to the path you specify. Every relative path you type afterward, in ls, cat, cp, or any other command, is interpreted relative to this new location until you cd somewhere else.
What is the difference between cd, cd ~, and cd with no argument?
Running cd with no argument at all takes you to your home directory, exactly the same as cd . The tilde () is a shorthand the shell expands to your home directory path before running the command. cd ~username expands to another user’s home directory instead, such as cd ~alice going to /home/alice, assuming you have permission to enter it.
What does cd - do?
cd - takes you back to the previous directory you were in before your last cd command, and prints that path to the screen. It toggles between your two most recent locations, which is useful for quickly bouncing back and forth between two directories, like a project folder and a configuration directory, without retyping the full path each time.
What is the difference between an absolute path and a relative path with cd?
An absolute path starts with a forward slash and is interpreted from the root directory regardless of where you currently are, such as cd /var/log. A relative path is interpreted starting from your current location, such as cd ../sibling-folder, which goes up one directory and then into sibling-folder. Absolute paths always land you in the same place; relative paths depend entirely on where you started.
Why is cd a shell builtin instead of a separate program?
A separate program runs in its own child process, and a child process cannot change the working directory of its parent shell, only its own. If cd were an external program, running it would change the directory inside that short-lived child process and then have no effect at all once the program exited, leaving your actual shell exactly where it started. Because cd must directly modify the current shell’s state, it has to be built into the shell itself rather than implemented as a standalone executable.
How do I quickly go back multiple directory levels at once?
Chain multiple ../ segments in a single relative path, such as cd ../../.. to go up three levels at once, rather than running cd .. three separate times. For frequently visited distant directories, many people instead define a shell alias or use pushd and popd, which maintain a stack of directories you can jump between with dirs, pushd, and popd.