Linux Filesystem Hierarchy Explained

Linux Filesystem Hierarchy Explained

The Linux Filesystem Hierarchy is a key concept you will need to understand. When working on the command line in Linux, you need to have a way to get around so to speak. When all you have is a cursor just blinking at you, it can give the feeling of “ok, what now”? Well, there are a handful of commands to let you begin to navigate around the hierarchy of the Linux filesystem. In this episode we’ll take a look at a few of them starting with pwd, which prints the current working directory, cd, which allows us to change to another directory, and ls, which provides the ability to quickly list the files and folders contained within a directory.

The Linux Filesystem Is Like A Tree

When we say that Linux has a hierarchical directory structure, what we mean is that the operating system is laid out in a tree like structure. Each branch may contain additional branches and so on. Windows also has this type of organization. So what is the starting point of all of this? It all boils down to the root directory. Everything begins at the root. This means that no matter what is connected to the Linux system, such as external storage devices, Linux always maintains one single filesystem tree. This is why you see storage as mounted or attached in Linux. This is in contrast to Windows which allows multiple filesystems based on the number of storage devices connected.

Let The Lost Be Found

In Windows, it is always pretty easy to see where you are in the filesystem. If you have windows explorer open, you’ll be able to see all of the folders connected with small lines to indicate where you are. In Linux there is a command to help you find where you are, and that command is pwd. For example in our homestead box when we SSH into it, we can find out where we are like so:

vagrant@homestead:~$ pwd

Now recall that what becomes before the @ sign is the user and what comes after the @ sign is the machine name. Now, before we even ran the pwd command, we were given a hint by the prompt which has a ~ tilde character in it. What this tilde character says is that you are located in the current user directory. Since we are logged in as vagrant, then we can know that /home/vagrant is where we are. Running the pwd command did in fact confirm this for us!

View Directory Contents

The whole point of directories is to hold data for us. We can list the contents of any given directory with the ls command. This command is simple enough, let’s try it out.

vagrant@homestead:~$ ls

This is pretty simple. We have a directory named Code within our vagrant user directory. Now all commands may have various options or switches associated with them. What this means is that you can add a lowercase or uppercase letter prefixed by the - sign or double -- sign to change the behavior of the command. We can view all potential options with the man command. Let’s look at all the options available to us for the ls command, you’ll be surprised how granular this can be.

vagrant@homestead:~$ man ls
LS(1) User Commands LS(1)

ls – list directory contents

ls [OPTION]… [FILE]…

List information about the FILEs (the current directory by default). Sort entries
alphabetically if none of -cftuvSUX nor –sort is specified.

Mandatory arguments to long options are mandatory for short options too.

-a, –all
do not ignore entries starting with .

-A, –almost-all
do not list implied . and ..

with -l, print the author of each file

-b, –escape
print C-style escapes for nongraphic characters

scale sizes by SIZE before printing them. E.g., ‘–block-size=M’ prints sizes
in units of 1,048,576 bytes. See SIZE format below.

-B, –ignore-backups
do not list implied entries ending with ~

-c with -lt: sort by, and show, ctime (time of last modification of file status
information) with -l: show ctime and sort by name otherwise: sort by ctime,
newest first

-C list entries by columns

colorize the output. WHEN defaults to ‘always’ or can be ‘never’ or ‘auto’.
More info below

-d, –directory
list directory entries instead of contents, and do not dereference symbolic

-D, –dired
generate output designed for Emacs’ dired mode

-f do not sort, enable -aU, disable -ls –color

-F, –classify
append indicator (one of */=>@|) to entries

likewise, except do not append ‘*’

across -x, commas -m, horizontal -x, long -l, single-column -1, verbose -l,
vertical -C

like -l –time-style=full-iso

-g like -l, but do not list owner

group directories before files.

augment with a –sort option, but any use of –sort=none (-U) disables group‐

-G, –no-group
in a long listing, don’t print group names

-h, –human-readable
with -l, print sizes in human readable format (e.g., 1K 234M 2G)

–si likewise, but use powers of 1000 not 1024

-H, –dereference-command-line
follow symbolic links listed on the command line

follow each command line symbolic link that points to a directory

do not list implied entries matching shell PATTERN (overridden by -a or -A)

append indicator with style WORD to entry names: none (default), slash (-p),
file-type (–file-type), classify (-F)

-i, –inode
print the index number of each file

-I, –ignore=PATTERN
do not list implied entries matching shell PATTERN

-k, –kibibytes
use 1024-byte blocks

-l use a long listing format

-L, –dereference
when showing file information for a symbolic link, show information for the
file the link references rather than for the link itself

-m fill width with a comma separated list of entries

-n, –numeric-uid-gid
like -l, but list numeric user and group IDs

-N, –literal
print raw entry names (don’t treat e.g. control characters specially)

-o like -l, but do not list group information

-p, –indicator-style=slash
append / indicator to directories

-q, –hide-control-chars
print ? instead of non graphic characters

show non graphic characters as-is (default unless program is ‘ls’ and output
is a terminal)

-Q, –quote-name
enclose entry names in double quotes

use quoting style WORD for entry names: literal, locale, shell, shell-always,
c, escape

-r, –reverse
reverse order while sorting

-R, –recursive
list subdirectories recursively

-s, –size
print the allocated size of each file, in blocks

-S sort by file size

sort by WORD instead of name: none -U, extension -X, size -S, time -t, version

with -l, show time as WORD instead of modification time: atime -u, access -u,
use -u, ctime -c, or status -c; use specified time as sort key if –sort=time

with -l, show times using style STYLE: full-iso, long-iso, iso, locale, +FOR‐
MAT. FORMAT is interpreted like ‘date’; if FORMAT is FORMAT1FORMAT2,
FORMAT1 applies to non-recent files and FORMAT2 to recent files; if STYLE is
prefixed with ‘posix-‘, STYLE takes effect only outside the POSIX locale

-t sort by modification time, newest first

-T, –tabsize=COLS
assume tab stops at each COLS instead of 8

-u with -lt: sort by, and show, access time with -l: show access time and sort by
name otherwise: sort by access time

-U do not sort; list entries in directory order

-v natural sort of (version) numbers within text

-w, –width=COLS
assume screen width instead of current value

-x list entries by lines instead of by columns

-X sort alphabetically by entry extension

-Z, –context
print any SELinux security context of each file

-1 list one file per line

–help display this help and exit

output version information and exit

SIZE is an integer and optional unit (example: 10M is 10*1024*1024). Units are K, M,
G, T, P, E, Z, Y (powers of 1024) or KB, MB, … (powers of 1000).

Using color to distinguish file types is disabled both by default and with
–color=never. With –color=auto, ls emits color codes only when standard output is
connected to a terminal. The LS_COLORS environment variable can change the settings.
Use the dircolors command to set it.

Exit status:
0 if OK,

1 if minor problems (e.g., cannot access subdirectory),

2 if serious trouble (e.g., cannot access command-line argument).

Written by Richard M. Stallman and David MacKenzie.

Report ls bugs to
GNU coreutils home page:
General help using GNU software:
Report ls translation bugs to

Copyright © 2013 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or
later .
This is free software: you are free to change and redistribute it. There is NO WAR‐
RANTY, to the extent permitted by law.

The full documentation for ls is maintained as a Texinfo manual. If the info and ls
programs are properly installed at your site, the command

info coreutils ‘ls invocation’

should give you access to the complete manual.

GNU coreutils 8.21 January 2015 LS(1)
Manual page ls(1) line 180/233 (END) (press h for help or q to quit)

The best thing to do is to simply have a play around with some of the various options for yourself. This will get you familiar with some of the different options behaviors.

Change Directories In Linux

Where ever you are currently located in the tree structure of the filesystem, you can move to a different location using the cd command. This of course allows you to change directories. It’s a simple command to use, all you need to do is type cd with the pathname of where you would like to go to. The pathname is the way you reach a working directory in the tree. For example, maybe you’d like to get to the etc directory to see what is in there. If you simply type cd etc, you will get an error. This is because the pathname is not complete. We need to include the full path name. Here is an example of trying to change directories, getting an error, and then successfully changing to the desired directory and viewing all of the contents with ls.

vagrant@homestead:~$ cd etc
-bash: cd: etc: No such file or directory
vagrant@homestead:~$ cd /etc
vagrant@homestead:/etc$ ls
acpi ghostscript manpath.config redis
adduser.conf groff memcached.conf request-key.d
adjtime group mime.types resolvconf
alternatives group- mke2fs.conf resolv.conf
apache2 grub.d modprobe.d rmt
apm gshadow modules rpc
apparmor gshadow- mtab rsyslog.conf
apparmor.d gssapi_mech.conf mysql rsyslog.d
apport hdparm.conf nanorc screenrc
apt hhvm netconfig securetty
at.deny host.conf network security
bash.bashrc hostname networks selinux
bash_completion hosts newt services
bash_completion.d hosts.allow nginx sgml
bindresvport.blacklist hosts.deny nsswitch.conf shadow
blackfire idmapd.conf opt shadow-
blkid.conf ImageMagick os-release shells init overlayroot.conf skel
byobu init.d overlayroot.local.conf ssh
ca-certificates initramfs-tools pam.conf ssl
ca-certificates.conf inputrc pam.d subgid
calendar insserv papersize subgid-
chatscripts insserv.conf passwd subuid
chef insserv.conf.d passwd- subuid-
cloud iproute2 pear sudoers
console-setup issue perl sudoers.d
cron.d php5 supervisor
cron.daily kbd pm sysctl.conf
cron.hourly kernel polkit-1 sysctl.d
cron.monthly kernel-img.conf pollinate systemd
crontab landscape popularity-contest.conf terminfo
cron.weekly ldap postgresql timezone
crypttab postgresql-common ucf.conf
dbus-1 ppp udev
debconf.conf profile ufw
debian_version legal profile.d updatedb.conf
default libaudit.conf protocols update-manager
deluser.conf libpaper.d puppet update-motd.d
depmod.d locale.alias python update-notifier
dhcp localtime python2.7 upstart-xsessions
dkms logcheck python3 vim
dpkg login.defs python3.4 vmware-tools
drirc logrotate.conf rc0.d vtrgb
ec2_version logrotate.d rc1.d w3m
emacs lsb-release rc2.d wgetrc
environment ltrace.conf rc3.d X11
fonts magic rc4.d xdg
fstab magic.mime rc5.d xml
fstab.d mailcap rc6.d zsh_command_not_found
fuse.conf mailcap.order rc.local
gai.conf mailname rcS.d

Relative Path Names And Shortcuts

When moving around to different directories, we can use absolute paths like we did above, or relative paths. Relative paths make use of the . and .. operators. The .. operator means to go up one directory to the parent. You can combine this multiple times as needed. For example if you need to get to the parent of the parent, you simply type cd ../.. The .. operator is very useful and you will make use of it constantly. The . operator is to go in the other direction so to speak. This says to move relative to the current working directory. Most times you don’t even need this, since it is implied. To prove this we can use absolute, relative, and implied relative in this example.

vagrant@homestead:/boot$ cd /boot/grub
vagrant@homestead:/boot/grub$ pwd
vagrant@homestead:/boot/grub$ cd ..
vagrant@homestead:/boot$ cd ./grub
vagrant@homestead:/boot/grub$ pwd
vagrant@homestead:/boot/grub$ cd ..
vagrant@homestead:/boot$ cd grub
vagrant@homestead:/boot/grub$ pwd

Note that all three approaches bring us to the same destination. The cd command also has some helpful shortcuts by the way of cd, cd -, and cd ~user. Here is what they accomplish for you:



cd Go from the current working directory to the home directory
cd – Go to the previous working directory
cd ~user Goes from te current working directory to the home directory of the user. For example cd ~vagrant goes to the home directory of user vagrant.

Linux Filesystem Hierarchy Conclusion

In this episode, we had a nice introduction to navigating our way through the tree like structure of the Linux Filesystem. By making use of some basic commands, we can see where we are, list directory contents, change working directories, and more. From here one, it’s just a matter of practicing these commands every day to be fluent in them.