Before computers, documents were stored as paper copies and organized into folders, then boxes, then filing cabinets, and those filing cabinets were stored in office rooms, taking up a lot of space and often not adding much to the aesthetic value of a room.
Today, a lot of documents are digital, and the computers they're stored on take up far less space than filing cabinets, and the aesthetic possibilities are mindbogglingly close to infinite! Just ask anyone who's deep in the world of mechanical keyboards!
With all these files in our computers, we still maintain a pretty similar structure to the old ways of document storage. Files are stored in folders, which are in other folders, and theoretically this folders-in-folders point could go on for a very long time. Well, that's all well and good, but what's it got to do with the command line and terminals and REPLs?
When you give the shell program in your terminal a command, it uses its current location in the file system as a reference point. You could think of each folder or directory in the file system as a room. Inside of each room is:
- a door to go one level up
- the files inside of each room, with a name and other information like date of creation
- any doors that go one level deeper into the file system
The shell can see all of this, and the most common commands you'll use involve navigating the file system and getting information about the objects inside of it.
Let's look at a few.
The Room I Start In
When you open a terminal, on most modern Linux systems you'll get something like this:
[stephen@virtualbox ~]$ []
Where it has information about the user (stephen
), the computer
(virtualbox
), and also the current directory. The squiggly ~
or tilde is a
convention that simply refers to your user's home directory.
From the way I wrote that, you may think "Well hold on, what's a home directory? And does every user have one?" And these are great, natural questions!
To answer the second question first: yes! Every user on a typical Linux machine has their own home directory, that other non-administrator users can't access. It's quite similar to any other multi-user accounts, like how you might have multiple users on a streaming service account, or how you can't see the email inboxes of your coworkers.
For the first question, a home directory is just somewhere in the file system you can put files (and whatever that entails, like projects, videos, and so on) that is a space for you. Like your home, or your room at your parents' house.
Simple Navigation
Now, let's see what's inside this room. We use the command ls
to do this:
[stephen@virtualbox ~]$ ls
Desktop Documents Downloads Music Pictures Public Templates Videos
[stephen@virtualbox ~]$
On this machine, all I have in my home directory is a bunch of empty folders. Seeing as I just set this virtual machine up, that's not a surprise.
Now, suppose you want to see what downloads you have on the computer. You can
use the command cd
, short for "change directory", followed by the folder name:
[stephen@virtualbox ~]$ cd Downloads/
[stephen@virtualbox Downloads]$ ls
[stephen@virtualbox Downloads]$
You may notice, the "~" has turned into the word "Downloads". Nifty!
We can also see that, as the result of the ls
command this time was nothing,
there aren't any files or folders in here. An empty room.
Command Options
How can we get back? Before we do that, let's try a modified ls
command. Use
ls -a
instead:
[stephen@virtualbox Downloads]$ ls -a
. ..
With the addition of the "-a", we gave the ls
command an option,
specifically an option that we want to show all the files, even the hidden ones.
"Dash-little-a" for "all" - simple!
This time it showed us two very strange "files": a dot, and two dots.
Similar to the tilde being shorthand for "user's home directory", these two file names are conventional. The single dot refers to "this current directory", while the two-dot file refers to "the directory one level up".
So what happens if we try to cd .
?
[stephen@virtualbox Downloads]$ cd .
[stephen@virtualbox Downloads]$
Evidently, nothing! This isn't terribly useful with the two commands we know now, but it can be very handy with other commands.
Before we try to change to the directory one level up, let's introduce a new
command, pwd
, or "print working directory":
[stephen@virtualbox Downloads]$ pwd
/home/stephen/Downloads
This tells us all the directories up we can go from the current directory, which
is related to where we go with cd ..
:
[stephen@virtualbox Downloads]$ cd ..
[stephen@virtualbox ~]$ pwd
/home/stephen
As you can see, we went up one directory from the Downloads
directory, and that
brought us back to ~
. But recall that ~
is shorthand, and the full path to
get to ~
is actually /home/stephen
.
Path is another common term, and it just means, in the rooms analogy, the path of rooms you would navigate to get to a location. In the usual terminology, it's the directories you navigate to get to a file or folder. You may also hear "file path".
Relative and Absolute Paths
When we first used the cd
command, we used it to move into the Downloads
folder. When we did, we supplied a relative path - in that case, Downloads
.
It's a relative path because relative to the starting location, it looked for
the directory named Downloads
, found it, and moved into that location. If we
were in another directory that also had a Downloads
folder, the same command
would work, we would just be in a different folder than the one we ended up in.
By contrast, when we used the pwd
command from inside the Downloads
folder,
we saw more than just the folder name - we saw /home/stephen/Downloads
. That
is the absolute path of the Downloads
folder, so-called because an absolute
path can never be mistaken for any other path. If you were to
cd /home/stephen/Downloads
, you will always go to the same location no matter
where you start from.
Let's look at how relative paths may lead to confusion:
[stephen@virtualbox Examples]$ ls
Downloads
[stephen@virtualbox Examples]$ pwd
/home/stephen/Examples
[stephen@virtualbox Examples]$ cd Downloads/ # Usage 1
[stephen@virtualbox Downloads]$ pwd
/home/stephen/Examples/Downloads
[stephen@virtualbox Downloads]$ cd ~
[stephen@virtualbox ~]$ cd Downloads/ # Usage 2
[stephen@virtualbox Downloads]$ pwd
/home/stephen/Downloads
Notice how the lines marked Usage 1
and Usage 2
are the same command:
cd Downloads/
, and yet pwd
gave different results afterwards.
Now let's see how we could navigate to the same folders with absolute paths:
[stephen@virtualbox Public]$ pwd
/home/stephen/Public
[stephen@virtualbox Public]$ cd /home/stephen/Examples/Downloads/
[stephen@virtualbox Downloads]$ pwd
/home/stephen/Examples/Downloads
[stephen@virtualbox Downloads]$ cd ~/Downloads/ # you can use ~ in place of typing out your home directory in commands!
[stephen@virtualbox Downloads]$ pwd
/home/stephen/Downloads
Fancy!
More Commands
So far, we've learned only 3 commands:
ls
for listing the contents of the directory we're incd
for moving between directoriespwd
to see what directory we're in, as an absolute path
This is a great baseline for navigating the file system, but we don't yet have any commands for manipulating the file system - creating files, deleting files, renaming files, and doing the same with directories. Now that we have a basic understanding of the file system, we can introduce these without too much additional explanation.
Creating Files with touch
With the command touch
followed by a file name, you can create an empty file
with the given name:
[stephen@virtualbox Examples]$ touch my_file.txt
[stephen@virtualbox Examples]$ ls
Downloads my_file.txt
[stephen@virtualbox Examples]$ touch my_file.txt
[stephen@virtualbox Examples]$ ls
Downloads my_file.txt
Notice that trying to touch
the same file name twice didn't result in 2 files.
In fact, touch
does something different with existing files. Let's take a look
at what it does by using a different option for ls
, this time the -l
option
for the "long listing" format.
[stephen@virtualbox Examples]$ ls -l
total 4
drwxr-xr-x 2 stephen stephen 4096 6月 5 16:16 Downloads
-rw-r--r-- 1 stephen stephen 0 6月 5 16:58 my_file.txt
# ^-- look here!
[stephen@virtualbox Examples]$ touch my_file.txt
[stephen@virtualbox Examples]$ ls -l
total 4
drwxr-xr-x 2 stephen stephen 4096 6月 5 16:16 Downloads
-rw-r--r-- 1 stephen stephen 0 6月 5 16:59 my_file.txt
# ^-- look here!
The ls -l
form gives some extra information beyond just the name of each file.
We won't dive too deep into this for now, but if you'd like to know what they
are, in order:
-
is the file type. This first character is shorthand, with the most common characters being-
for a regular file,d
for directory, orl
for a link - we won't discuss links too much in this book, though.rw-r--r--
is the permissions of the file, wherer
stands for read,w
stands for write, andx
stands for execute. There are three separate permission groupings: owner, group, and "all" for everyone else. They're divided into 3 groupings of 3, with dashes representing permissions the grouping has: in this example, the owner has read and write permissions, while the group and everyone else only has read permission1
is the number of links to the filestephen
andstephen
are the owner and group of the file. These are the same on this personal system, but they won't always be!0
is the size of the file. Since it's empty, it has a size of 0. Directories will always have a fixed size of 4096, or 4 kilobytes6月 5 16:59
is the time the file was last modified - this is a Japanese output format in my case, since my machine is located in Japan- And lastly,
my_file.txt
is the name of the file
The result of touch
in the above example was the modification time being
updated to the time of the command, which is what touch
does to files that
already exist. If they don't exist, then it instead creates an empty file with
the given name.
Deleting Files with rm
To delete a file, use the rm
command (short for "remove") followed by the file
name:
[stephen@virtualbox Examples]$ ls
Downloads my_file.txt
[stephen@virtualbox Examples]$ rm my_file.txt
[stephen@virtualbox Examples]$ ls
Downloads
Farewell, my_file.txt
! The only other note I have on this is you should
never run this command:
rm -rf /
This command deletes every file on the file system and it is a very, very bad idea. Don't do it!
To understand how it works:
- the
-r
option is short for "recursive", meaning the command will delete everything under the given directory - the
-f
option is short for "force", meaning the command will not ask for any confirmations to delete protected files and such, it will simply destroy them - the folder name given to it,
/
, means the top of the file system. There's nothing above this, so it's also called the root of the file system
Now, while this specific command is extremely dangerous, the two options can be very useful both by themselves, and when combined but with a different folder name. Clearing out data from a big directory is one example. Just double check what the folder name is before you hit "Enter"!
Creating Directories with mkdir
Creating directories is done with the mkdir
command:
[stephen@virtualbox Examples]$ ls
Downloads
[stephen@virtualbox Examples]$ mkdir MyDirectory
[stephen@virtualbox Examples]$ ls
Downloads MyDirectory
Simple! We can also use the -p
option to create multiple subdirectories at
once, since the standard behavior only expects one new "level" of directory:
[stephen@virtualbox Examples]$ mkdir MyDirectory/AnotherDir/AndAnother
mkdir: cannot create directory ‘MyDirectory/AnotherDir/AndAnother’: No such file or directory
[stephen@virtualbox Examples]$ mkdir -p MyDirectory/AnotherDir/AndAnother
[stephen@virtualbox Examples]$ cd MyDirectory/AnotherDir/AndAnother/
[stephen@virtualbox AndAnother]$ ls
[stephen@virtualbox AndAnother]$ pwd
/home/stephen/Examples/MyDirectory/AnotherDir/AndAnother
Deleting Directories with rmdir
To delete empty directories, we can use rmdir
, short for "remove directory":
[stephen@virtualbox Examples]$ mkdir SomeDirectory
[stephen@virtualbox Examples]$ ls
Downloads SomeDirectory
[stephen@virtualbox Examples]$ rmdir SomeDirectory/
[stephen@virtualbox Examples]$ ls
Downloads
As an inverse to mkdir -p
, we can do rmdir -p
for multiple levels of empty
subdirectories:
[stephen@virtualbox Examples]$ mkdir -p MyDirectory/AnotherDir/AndAnother
[stephen@virtualbox Examples]$ rmdir -p MyDirectory/AnotherDir/AndAnother
[stephen@virtualbox Examples]$ ls
Downloads
Renaming Files and Directories with mv
Renaming files and directories is done with the same command, mv
, short for
"move". It needs the target file or directory, as well as the new name for the
target, like so:
[stephen@virtualbox Examples]$ mkdir -p MyDirectory/AnotherDir
[stephen@virtualbox Examples]$ ls
Downloads MyDirectory
[stephen@virtualbox Examples]$ mv MyDirectory/ OrIsItYourDirectory
[stephen@virtualbox Examples]$ ls
Downloads OrIsItYourDirectory
[stephen@virtualbox Examples]$ touch my_file.txt
[stephen@virtualbox Examples]$ mv my_file.txt or_is_it_your_file.txt
[stephen@virtualbox Examples]$ ls
Downloads OrIsItYourDirectory or_is_it_your_file.txt
You can also use mv
to move files into directories:
[stephen@virtualbox Examples]$ mkdir Stuff
[stephen@virtualbox Examples]$ touch my_file.txt
[stephen@virtualbox Examples]$ ls
my_file.txt Stuff
[stephen@virtualbox Examples]$ mv my_file.txt Stuff/
[stephen@virtualbox Examples]$ ls
Stuff
[stephen@virtualbox Examples]$ cd Stuff/
[stephen@virtualbox Stuff]$ ls
my_file.txt
Summary
In this chapter, we looked at the basics of the file system on Linux, how this relates to the terminal, and how we can basically navigate around the file system with the terminal.
In the next chapter, we'll be taking a closer look at files and programs and how, ultimately, they are not so different!