Getting Started With the cd Command

The cd command is used on the Linux command line to change from one directory to another. When working at the command line, moving between directories is a common task which can result in a significant reduction in typing long path names. As a Lazy SysAdmin, reducing the amount of typing I do makes my work easier and me more productive.

Like many Linux, and Unix, commands it’s name is short and meaningful, “change directory.” This article looks at how the cd command works as a regular, non-root user, and some of its interesting yet lesser known but time-saving capabilities.

First, let’s look at the storage structure that makes commands like cd necessary.

The Directory Tree

Like most operating systems, Linux uses a tree-like structure for data storage. The tree starts at the root directory (/) and branches off into sub-directories that provide a means to organize the files on a computer.

The structure used by Linux was first designed and implemented on Unix in 1969, and it’s codified in the Linux Filesystem Hierarchical Standard (FHS). For this article, we’re only interested in the home directory for a single user, me.

You can see below, the result of a tree command for the /home directory which contains the home directory for my test user as well as the home directories myself and for other users if there were any. The d option specifies that we want to see only directories, and the L2 option specifies that the filesystem tree will only be listed to 2 levels deep which significantly reduces the amount of output from the command.

tuser1@essex:~$ tree -dL2 /home
/home
├── dboth  [error opening dir]
├── lost+found  [error opening dir]
└── tuser1
    ├── Desktop
    ├── Documents
    ├── Downloads
    ├── Music
    ├── Pictures
    ├── Public
    ├── Templates
    └── Videos

12 directories

You can see from this, the very basic default directory structure for a newly created user. This is what you’d see for a new user on most distributions so you wouldn’t need the L2 option. Most of us will need that when exploring our own home directories.

Note that the test user cannot access the contents of the other two directories in /home, as they don’t have permissions to do so.

You might want to experiment with the options on this command for your own system so you can see the full depth of the directory structure as well as the files it contains.

The PWD

The term “PWD” refers to present working directory, which you might know as the “current directory.” The PWD is important because all command actions take place in the PWD unless another location is explicitly specified in the command. The pwd command means “print working directory,” that is, print the name of the current directory on the terminal display.

tuser1@essex:~$ pwd
/home/tuser1
tuser1@essex:~$

Directory path notation styles

A path is a notational method for referring to directories in the Linux directory tree. This gives us a method for expressing the path to a directory or a file that is not in the pwd. Linux uses paths extensively for easy location of and access to executable files, making it unnecessary to type the entire path to the executable.

For example, it is easier to type “ls” than it is to type “/usr/bin/ls” to run the ls command. The shell uses the PATH variable where it finds a list of directories in which to search for the executable by the name “ls”.

This simple experiment simply displays the content of the PATH environment variable for the test user.

tuser1@essex:~$ echo $PATH
/home/tuser1/.local/bin:/home/tuser1/bin:/usr/lib64/qt-3.3/bin:/usr/local/bin:/usr/bin
tuser1@essex:~$

The various paths – directories – that the shell will search are listed in the output from the above command. Each path is separated by a colon (:).

There are two types of notation we can use to express a path – absolute and relative. An absolute path is specified completely starting with the root directory. So if the PWD is the Downloads directory of my home directory, I would specify the absolute path as /home/student/Downloads. With that as my PWD, if I need to specify the absolute path to my Documents/Work directory as /home/student/Documents/Work. I could also specify that path in relative notation from my current PWD as, ../Documents/Work. I could also use the notation, ~/Documents/Work because the Tilde (~) is a shorthand notation for my home directory.

Moving around the directory tree

Let’s start by looking at how to move around the Linux filesystem directory tree at the command line. Many times working on or in a directory is easier if it is the PWD. Moving around the filesystem is a very important capability and there are a number of shortcuts that can help as well.

Perform this little experiment as a test user, tuser1 in my case. You should already be logged into your computer with terminal session open as your test user. If not, do that now.

Moving around the Linux filesystem directory tree is important for many reasons. Start by using the pwd command to display the PWD.

The first time I checked, the pwd was the /tmp directory because I had been working there. Your PWD will probably be your home directory, (~). Using the cd command with no options always makes your home directory the PWD. Notice in the command prompt that the tilde (~) is a shorthand indicator for your home directory.

tuser1@essex:/tmp$ pwd
/tmp
tuser1@essex:/tmp$ cd
tuser1@essex:~$ pwd
/home/tuser1
tuser1@essex:~$

Now just do a simple command, long list, to view the content of your home directory. These directories are created when a new user logs in to the account using the GUI for the first time.

tuser1@essex:~$ ls -l
total 32
drwxr-xr-x 2 tuser1 tuser1 4096 Feb  9 08:20 Desktop
drwxr-xr-x 2 tuser1 tuser1 4096 Feb  9 08:20 Documents
drwxr-xr-x 2 tuser1 tuser1 4096 Feb  9 08:20 Downloads
drwxr-xr-x 2 tuser1 tuser1 4096 Feb  9 08:20 Music
drwxr-xr-x 2 tuser1 tuser1 4096 Feb  9 08:20 Pictures
drwxr-xr-x 2 tuser1 tuser1 4096 Feb  9 08:20 Public
drwxr-xr-x 2 tuser1 tuser1 4096 Feb  9 08:20 Templates
drwxr-xr-x 2 tuser1 tuser1 4096 Feb  9 08:20 Videos
tuser1@essex:~$

This command does not show the so-called hidden files in your home directory which makes it easier to scan the rest of the contents.

Let’s create a few files to work with since there are none other than the hidden configuration files created by default. The following command line program will create 50 text files that have a bit of data in them so we have more than just directories to look at. Enter the program all on one line. It is OK if the line wraps on your screen, just do not press Enter until you have completed the entire command. Then list the contents of the home directory.

tuser1@essex:~$ for X in `seq -w 1 50` ; do echo "This is file $X.txt" > file$X.txt ; done
tuser1@essex:~$ ls
Desktop     file04.txt  file10.txt  file16.txt  file22.txt  file28.txt  file34.txt  file40.txt  file46.txt  Pictures
Documents   file05.txt  file11.txt  file17.txt  file23.txt  file29.txt  file35.txt  file41.txt  file47.txt  Public
Downloads   file06.txt  file12.txt  file18.txt  file24.txt  file30.txt  file36.txt  file42.txt  file48.txt  Templates
file01.txt  file07.txt  file13.txt  file19.txt  file25.txt  file31.txt  file37.txt  file43.txt  file49.txt  Videos
file02.txt  file08.txt  file14.txt  file20.txt  file26.txt  file32.txt  file38.txt  file44.txt  file50.txt
file03.txt  file09.txt  file15.txt  file21.txt  file27.txt  file33.txt  file39.txt  file45.txt  Music
tuser1@essex:~$

Now do a long listing of the directory.

tuser1@essex:~$ ls -l
total 232
drwxr-xr-x 2 tuser1 tuser1 4096 Feb  9 08:20 Desktop
drwxr-xr-x 2 tuser1 tuser1 4096 Feb  9 08:20 Documents
drwxr-xr-x 2 tuser1 tuser1 4096 Feb  9 08:20 Downloads
-rw-r--r-- 1 tuser1 tuser1   20 Feb 10 16:43 file01.txt
-rw-r--r-- 1 tuser1 tuser1   20 Feb 10 16:43 file02.txt
-rw-r--r-- 1 tuser1 tuser1   20 Feb 10 16:43 file03.txt
-rw-r--r-- 1 tuser1 tuser1   20 Feb 10 16:43 file04.txt
-rw-r--r-- 1 tuser1 tuser1   20 Feb 10 16:43 file05.txt
-rw-r--r-- 1 tuser1 tuser1   20 Feb 10 16:43 file06.txt
-rw-r--r-- 1 tuser1 tuser1   20 Feb 10 16:43 file07.txt
-rw-r--r-- 1 tuser1 tuser1   20 Feb 10 16:43 file08.txt
-rw-r--r-- 1 tuser1 tuser1   20 Feb 10 16:43 file09.txt
-rw-r--r-- 1 tuser1 tuser1   20 Feb 10 16:43 file10.txt
-rw-r--r-- 1 tuser1 tuser1   20 Feb 10 16:43 file11.txt
-rw-r--r-- 1 tuser1 tuser1   20 Feb 10 16:43 file12.txt
-rw-r--r-- 1 tuser1 tuser1   20 Feb 10 16:43 file13.txt
-rw-r--r-- 1 tuser1 tuser1   20 Feb 10 16:43 file14.txt
<SNIP>
-rw-r--r-- 1 tuser1 tuser1   20 Feb 10 16:43 file46.txt
-rw-r--r-- 1 tuser1 tuser1   20 Feb 10 16:43 file47.txt
-rw-r--r-- 1 tuser1 tuser1   20 Feb 10 16:43 file48.txt
-rw-r--r-- 1 tuser1 tuser1   20 Feb 10 16:43 file49.txt
-rw-r--r-- 1 tuser1 tuser1   20 Feb 10 16:43 file50.txt
drwxr-xr-x 2 tuser1 tuser1 4096 Feb  9 08:20 Music
drwxr-xr-x 2 tuser1 tuser1 4096 Feb  9 08:20 Pictures
drwxr-xr-x 2 tuser1 tuser1 4096 Feb  9 08:20 Public
drwxr-xr-x 2 tuser1 tuser1 4096 Feb  9 08:20 Templates
drwxr-xr-x 2 tuser1 tuser1 4096 Feb  9 08:20 Videos
tuser1@essex:~$

This long listing shows the ownership and file permissions — also called the file mode — for each file and directory. The permissions drwxr-xr-x show first that this is a directory with the leading “d” while files have a dash (-) in that position. The file permissions are three triplets of (R)ead, (W)rite, and e(X)ecute. Each triplet represents User, the owner of the file, Group, the group that owns the file, and Other, for all other users. These permissions represent something a bit different on a directory.

Make /var/log the pwd and list the contents.

tuser1@essex:~$ cd /var/log
tuser1@essex:/var/log$ ls -l 
total 67348
drwxrwxr-x  2 root    akmods  4096 Feb  1 00:34 akmods
drwxr-xr-x. 2 root    root    4096 Jan 19 09:03 anaconda
-rw-r--r--  1 root    root     380 Feb  9 15:07 apcupsd.events
-rw-r--r--  1 root    root      82 Jan 25 00:38 apcupsd.events-20260125
-rw-r--r--  1 root    root    1263 Feb  1 00:34 apcupsd.events-20260201
-rw-r--r--  1 root    root     190 Feb  8 00:31 apcupsd.events-20260208
drwxr-xr-x. 2 root    root    4096 Sep 22 20:00 atop
drwx------. 2 root    root    4096 Jan 31 19:00 audit
drwxr-xr-x. 2 root    root    4096 Oct  5 20:00 blivet-gui
<SNIP>
drwxr-xr-x. 2 lightdm lightdm 4096 Feb  9 15:07 lightdm
drwxr-xr-x. 2 root    root    4096 Jan 19 09:27 mail
-rw-------  1 root    root   16358 Feb 10 03:28 maillog
-rw-------. 1 root    root   36582 Jan 25 00:00 maillog-20260125
-rw-------  1 root    root   42845 Feb  1 00:00 maillog-20260201
-rw-------  1 root    root   39499 Feb  8 00:00 maillog-20260208
-rw-------  1 root    root 7991182 Feb 10 19:01 messages
-rw-------. 1 root    root 9852761 Jan 25 00:38 messages-20260125
-rw-------  1 root    root 8093136 Feb  1 00:34 messages-20260201
-rw-------  1 root    root 6194218 Feb  8 00:31 messages-20260208
<SNIP>
lrwxrwxrwx. 1 root    root      39 Jan 19 08:59 README -> ../../usr/share/doc/systemd/README.logs
drwxr-xr-x. 2 root    root    4096 Feb  8 00:31 rkhunter
drwxr-xr-x. 2 root    root    4096 Feb 10 00:07 sa
drwx------. 3 root    root    4096 Jan 24 19:00 samba
-rw-------  1 root    root   18431 Feb 10 15:11 secure
-rw-------. 1 root    root   37914 Jan 25 00:20 secure-20260125
-rw-------  1 root    root   47704 Feb  1 00:17 secure-20260201
-rw-------  1 root    root   23208 Feb  8 00:17 secure-20260208
drwx------. 2 root    root    4096 Sep 18 20:00 speech-dispatcher
-rw-------  1 root    root       0 Feb  8 00:31 spooler
-rw-------. 1 root    root       0 Jan 19 09:00 spooler-20260125
-rw-------  1 root    root       0 Jan 25 00:38 spooler-20260201
-rw-------  1 root    root       0 Feb  1 00:34 spooler-20260208
drwxrwx---. 2 sssd    sssd    4096 Feb  8 00:31 sssd
-rw-rw-r--. 1 root    utmp  140160 Feb 10 15:11 wtmp
-rw-r--r--  1 root    root   87901 Feb 10 18:56 Xorg.0.log
-rw-r--r--  1 root    root   67064 Feb  9 15:05 Xorg.0.log.old
-rw-r--r--  1 root    root   46342 Feb  9 14:53 Xorg.1.log
-rw-r--r--  1 root    root   96904 Feb  9 14:52 Xorg.1.log.old
-rw-r--r--  1 root    root   46333 Feb  9 08:21 Xorg.2.log
tuser1@essex:/var/log$

Try to display the content of the messages file.

tuser1@essex:/var/log$ cat messages
cat: messages: Permission denied
tuser1@essex:/var/log$

If you are using Fedora like I do, there should be a README file in /var/log. Other distros should also have that README file. Just to do something while here, use the cat command to view the contents of this file.

tuser1@essex:/var/log$ cat README
You are looking for the traditional text log files in /var/log, and they are gone?

Here's an explanation on what's going on:
<SNIP>

Now change to the Documents sub-directory of your home directory (~).

tuser1@essex:/var/log$ cd ~/Documents/ ; ls -l
total 0
tuser1@essex:~/Documents$

Notice that I used the tilde (~) to represent the home directory which would otherwise have to be typed out as /home/student/Documents. When I want to return to the /var/log directory I can save a bit of typing using this next shortcut.

tuser1@essex:~/Documents$ cd -
/var/log
tuser1@essex:/var/log$

The dash (-), aka, the minus sign, will always return you to the previous PWD. How? Look a bit at the environment which defines many environment variables including $PWD and $OLDPWD. The env command prints all of the current environment variables and the grep command extracts and sends to STDOUT only those lines that contain “PWD”.

tuser1@essex:/var/log$ env | grep -i PWD
PWD=/var/log
OLDPWD=/home/tuser1/Documents
tuser1@essex:/var/log$

The dash (-), when used as an option to the cd command, is a shorthand notation for the $OLDPWD variable. The command could also be issued in the following manner.

tuser1@essex:/var/log$ cd $OLDPWD
tuser1@essex:~/Documents$

The cd command looks simple on the surface but it has some interesting capabilities that make moving around the Linux directory tree much easier if you know them.

Leave a Reply