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 Downloadsdirectory, 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 in
  • cd for moving between directories
  • pwd 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, or l for a link - we won't discuss links too much in this book, though.
  • rw-r--r-- is the permissions of the file, where r stands for read, w stands for write, and x 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 permission
  • 1 is the number of links to the file
  • stephen and stephen 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 kilobytes
  • 6月 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!