Series
This is part of a series about Bash and the Linux Shell.
The previous post looked at what Bash is and what it’s useful for.
In this post, we’ll look at the basics of getting started using Bash and the Linux Shell.
Introduction
As we discussed in the previous post, Bash is a popular tool created from the GNU project for interacting with your computer via text commands.
By using these commands in Bash you are able to work directly with your operating system and many of the powerful tools that it offers.
There are many tasks you can do on Linux (and other operating systems) through graphical user interfaces. But there are some things that can only be accomplished via text interfaces, like the shell. And many things can be done much more efficiently via the shell.
While there are ways to accomplish some of these steps through the graphical interface, for this post we’ll use just the keyboard for nearly everything.
For some people, it might feel awkward or slow to work with a computer by typing text at first. But you can quickly get past the learning curve. It doesn’t take long to learn the basics. Then you’ll have much greater control over your computer and soon you’ll likely find you can finish most tasks quicker this way.
That’s what we’re going to look at here.
We’ll learn just a few basics of Bash and the Linux Shell - just enough to get started.
Then you’ll have the skills and confidence to explore the topic more as your needs or curiosity leads you.
Context
In this post we’ll assume that Bash is installed and that all commands are entered in a Bash terminal.
While much of the information applies generally to Linux, some of the instructions will not apply to all systems. Specifically, program installation instructions focus on utilizing the package manager used by Debian and Ubuntu. Other distributions will require different installation steps.
The majority of these commands were tested on Bash 5.1.16 on Ubuntu 22.04.3 or later. They may behave differently on other systems.
Finally, much in Linux is based around the user and user-specific files. For our examples, we’ll reference the user name “Emerson”. Wherever you see Emerson substitute your user name.
An important note of caution
And one word of caution before proceeding.
Getting Started with Bash and the Linux Shell
Basic shell interactions
As we begin there are a few fundamental key combinations we’ll need to know.
You’ll need to press these keys simultaneously in order for them to work.
The first thing we’ll need to do is open a terminal window.
Press the keys:
CTRL
+ ALT
+ T
to open a new terminal window.
We’ll also want to be able to close the terminal window.
While in the terminal window you want to close, press the keys:
ALT
+ F4
to close the active terminal window.
And before we start entering commands it’s important to know how to stop a running command.
While in the terminal window running the command you want to stop, press the keys:
CTRL
+ C
to attempt to stop a running command.
Now, let’s once again press the keys CTRL
+ ALT
+ T
to open a new terminal window and get started.
The Bash prompt
When you open a new terminal you are likely shown an almost blank window with just a small amount of text in the upper left corner.
It typically looks something like:
user@computer:~$ █
For our example user it would look like:
Emerson@desktop:~$ █
This is the shell prompt, typically just called the prompt.
The blinking block is where the commands you type will appear.
Note: For the rest of this post, we’ll leave the text of the prompt out of the examples so that the commands are easy to read.
Getting output from Bash
Now let’s get some simple output from Bash.
date command
The date command from the GNU project displays the system date and time.
Enter the following at the prompt:
Command:
date
Example Output:
Fri 13 Oct 2023 01:53:17 PM GMT
Now try to capitalize it.
Command:
Date
Output:
Command 'Date' not found, did you mean:
command 'kate' from snap kate (23.04.3)
command 'gate' from snap gate (9.3)
command 'kate' from deb kate (4:21.12.3-0ubuntu1)
command 'late' from deb late (0.1.0-14)
command 'date' from deb coreutils (8.32-4.1ubuntu1)
See 'snap info <snapname>' for additional versions.
Note that commands in Bash are case sensitive.
You can also pass arguments to the date command to change it’s format. Try the following:
Command:
date '+%Y-%m-%d %T'
Example Output:
2023-09-01 14:04:34
echo command
The echo command from the GNU project displays text to the screen. Try the following:
Command:
echo Hello World
Output:
Hello World
The echo command can also print system variables. Try the following commands.
Command:
echo $SHELL
Output:
/bin/bash
Displays the content of the SHELL variable.
Command:
echo $PATH
Example Output:
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/snap/bin
Displays the content of the PATH variable.
Command:
echo $RANDOM
Example Output:
19853
Displays a pseudo-random number.
clear command
The clear command clears the output from the terminal window.
Command:
clear
Output:
history command
To see a history of the commands used in the terminal, use the history command from the GNU project.
Command:
history
Example Output:
1 date
2 Date
3 date '+%Y-%m-%d %T'
4 echo Hello World
5 echo $SHELL
6 echo $PATH
7 echo $RANDOM
8 clear
9 history
To see a history of only the last 5 commands enter the following.
Command:
history 5
Example Output:
6 echo $PATH
7 echo $RANDOM
8 clear
9 history
10 history 5
More Shell interactions
As we move along, there are a few more key combinations that are helpful to know.
For this combination, first use the mouse to highlight some text in the terminal and press the keys:
CTRL
+ SHIFT
+ C
to copy the highlighted text.
to paste text from the clipboard press the keys:
CTRL
+ SHIFT
+ V
Now use a key combination we learned previously:
CTRL
+ C
to move to the next prompt line without running the current line.
To cycle through previous commands use ↑ (the UP ARROW) and ↓ (the DOWN ARROW).
↑
↓
To auto-complete a partially-typed command type the first part of the command and then press the TAB key.
Partial Command:
ech
press the TAB
key:
Auto-Completed Command:
echo
Partial Command:
his
press the TAB
key:
Auto-Completed Command:
history
These key combinations will help you work more quickly with the shell.
Commands to learn about commands
As you use the terminal more regularly, you’ll likely want to learn more about commands before you run them.
--help
One easy approach that often works to learn more about a specific command is to type the command followed by the --help option.
Command:
history --help
Output:
history: history [-c] [-d offset] [n] or history -anrw [filename] or history -ps arg [arg...]
Display or manipulate the history list.
Display the history list with line numbers, prefixing each modified
entry with a `*'. An argument of N lists only the last N entries.
Options:
-c clear the history list by deleting all of the entries
-d offset delete the history entry at position OFFSET. Negative
offsets count back from the end of the history list
-a append history lines from this session to the history file
-n read all history lines not already read from the history file
and append them to the history list
-r read the history file and append the contents to the history
list
-w write the current history to the history file
-p perform history expansion on each ARG and display the result
without storing it in the history list
-s append the ARGs to the history list as a single entry
If FILENAME is given, it is used as the history file. Otherwise,
if HISTFILE has a value, that is used, else ~/.bash_history.
If the HISTTIMEFORMAT variable is set and not null, its value is used
as a format string for strftime(3) to print the time stamp associated
with each displayed history entry. No time stamps are printed otherwise.
Exit Status:
Returns success unless an invalid option is given or an error occurs.
--version
You can also learn version information in a similar way with the --version option.
Command:
bash --version
Output:
GNU bash, version 5.1.16(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
which command
It’s possible for multiple programs with the same name to be installed on a system. To see which one is called when you enter the program name, use the which command followed by the name of the command you want to check.
Command:
which echo
Output:
/usr/bin/echo
Displays the path to the program that is run when the command is entered.
man command
Many commands come with their own manual page, which can be displayed with the man command followed by the name of the command.
Command:
man date
Partial Output:
DATE(1) User Commands DATE(1)
NAME
date - print or set the system date and time
SYNOPSIS
date [OPTION]... [+FORMAT]
date [-u|--utc|--universal] [MMDDhhmm[[CC]YY][.ss]]
DESCRIPTION
Display the current time in the given FORMAT, or set the system date.
Mandatory arguments to long options are mandatory for short options too.
-d, --date=STRING
display time described by STRING, not 'now'
--debug
annotate the parsed date, and warn about questionable usage to stderr
-f, --file=DATEFILE
like --date; once for each line of DATEFILE
Manual page date(1) line 1/201 13% (press h for help or q to quit)
Important note: As stated in the last line, to exit the manual page, press q
.
Some manual pages contain a lot of detail. They are an essential tool, but they can also be quite daunting for new users.
For that reason we’ll next look at how to install another helpful tool.
Installing new programs
Installing software and using package managers are entire topics in their own right. We’re going to focus on installing one program as a simple example without touching on all the intricacies.
To aid in learning about other commands we’ll install the tldr command. It displays short, simple help pages for command line tools, from the user-maintained tldr-pages project. It is great for learning about other commands, but it does not come pre-installed.
There are various options for installation. On Ubuntu, the installation process is straightforward since it is available via the package manager. Other distributions will have different steps.
If you can’t figure out the process for your system (or just don’t want to install it) you can use tldr via the web app. There is even a PDF version available for offline use.
To install tldr on Ubuntu in a moment we’ll use the command: sudo apt install tldr
First though, let’s use the tldr web app to look at each part of that command.
sudo command
According to the tldr web app, sudo “[e]xecutes a single command as the superuser or another user.”
Superuser privileges are required for various system operations - like installing software - and the sudo command has various uses and hazards that you should learn about.
For now, it’s important to know that the sudo command is required to install software and will prompt you for your user password, which you should only supply if you understand what the command is doing and want to proceed.
apt command
Next, according to the tldr web app, apt from the Debian Linux distribution is the “[p]ackage management utility for Debian based distributions.” Ubuntu is a Debian-based distribution and utilizes apt as it’s package manager.
As the tldr page also shows, the command sudo apt install {{package}}
allows the user to “[i]nstall a package, or update it to the latest available version.”
In this case, the package we are interested in installing is tldr.
installing tldr
As mentioned above the command to install tldr on Ubuntu is:
Command:
sudo apt install tldr
Once entered, sudo will prompt for the user password before continuing. After the correct password is provided the installation process will begin.
Once completed, you can confirm the installation by checking the version.
Command:
tldr --version
Example Output:
0.6.4
If it installed correctly you will next need to update the offline cache of tldr pages with the command:
Command:
tldr --update
tldr command
Once it is installed, you can use tldr to see command summaries and examples:
Command form:
tldr {{command name}}
Example:
tldr tldr
Output:
tldr
Display simple help pages for command-line tools from the tldr-pages project.More information: https://tldr.sh.
- Print the tldr page for a specific command (hint: this is how you got here!):
tldr {{command}}
- Print the tldr page for a specific subcommand:
tldr {{command}}-{{subcommand}}
- Print the tldr page for a command for a specific [p]latform:
tldr -p {{android|linux|osx|sunos|windows}} {{command}}
- [u]pdate the local cache of tldr pages:
tldr -u
Look at a few more commands we’ve used:
tldr echo
tldr clear
tldr which
tldr man
Often tldr is faster and easier to understand than the results of the man command.
General information about commands
Now that we have some experience with several commands, let’s learn a little more about commands generally.
Definition of commands
According to Seth Kenlon
A command is a special keyword you can use in a terminal to tell your computer to perform an action. Most commands are tiny little applications that get installed with the rest of your operating system. You may not realize they’re on your computer because they’re generally kept in relatively obscure directories like /bin, /sbin, /usr/bin, and /usr/sbin, but your terminal knows where to find them (thanks to something called the PATH). Other commands are built into your terminal.
Commands can have several components (as this helpful StackExchange answer illustrates):
┌────1─────┐ ┌───2───┐ ┌───2───┐ ┌───2───┐
command-name argument1 argument2 argument3
└───────────────────3────────────────────┘
-
The command name
-
The arguments (also sometimes called options, flags, or switches).
-
The command line.
A command will always have a command name and may or may not have arguments, depending on the command. Taken together, they are referred to as a command line, or often simply as a command.
Continuing with a slighty amended portion of Seth Kenlon’s description:
An argument is any part of a command that isn’t the command [name].
Command options, also called flags or switches, are part of command arguments. A command argument is anything that follows a command, and an option is usually (but not always) demarcated by a dash or double dashes.
Examples of commands
Let’s look at some examples from commands we’ve already seen.
Command example 1
┌─1─┐
clear
└─3─┘
-
clear
is the command name. -
There are no arguments.
-
In this case,
clear
is the whole command line.
Command example 2
┌─1─┐ ┌─2─┐
which clear
└────3────┘
-
which
is the command name. -
clear
is the argument. -
which clear
is the command line.
Command example 3
┌──1──┐ ┌──2─┐
history --help
└──────3─────┘
-
history
is the command name. -
--help
is the argument, and might more likely be called an option because of the dashes. -
history --help
is the command line.
These are simple examples.
Later we’ll look at some commands with multiple arguments.
For now, it is enough to know the terminology and basic structure of commands.
Navigating the file system and examining files
For everything we’ve learned so far, we’ve stayed in one place. But the shell is a powerful tool for viewing and managing files and directories. (In case you’re not familiar with the terminology, a “directory” is sometimes called a “folder” on other operating systems.)
As the Ubuntu The Linux command line for beginners explains:
One important concept to understand is that the shell has a notion of a default location in which any file operations will take place. This is its working directory. If you try to create new files or directories, view existing files, or even delete them, the shell will assume you’re looking for them in the current working directory unless you take steps to specify otherwise. So it’s quite important to keep an idea of what directory the shell is “in” at any given time, after all, deleting files from the wrong directory could be disastrous. If you’re ever in any doubt, the pwd command will tell you exactly what the current working directory is.
pwd command
So, let’s start by figuring out where we are.
The pwd command (short for print working directory) from the GNU project tells us where we’re currently located within our file system in the terminal.
Command:
pwd
Output:
/home/Emerson
ls command
Now that we know where we are, let’s see what’s here.
The ls command from the GNU project lists the contents of a directory:
Command:
ls
Example Output:
Desktop Documents Downloads Music Pictures Public snap Templates Videos
The ls command has several helpful options. Check the tldr page to see a few.
Command:
tldr ls
Let’s try some.
Adding the a and 1 options displays all files (including hidden files) in a single column
Command:
ls -a1
Example Output:
.
..
.bash_history
.bash_logout
.bashrc
.cache
.cert
.config
.cxoffice
Desktop
Documents
Downloads
.gnupg
.lesshst
.local
.mozilla
Music
.pam_environment
Pictures
.pki
.profile
Public
snap
.ssh
.sudo_as_admin_successful
Templates
.var
Videos
.wget-hsts
Adding the l and h options displays contents in long format and the file sizes in “human-readable” units, like kilobytes and megabytes.
Command:
ls -lh
Example Output:
total 36K
drwxr-xr-x 2 Emerson Emerson 4.0K Dec 15 16:47 Desktop
drwxr-xr-x 4 Emerson Emerson 4.0K Aug 14 15:59 Documents
drwxr-xr-x 3 Emerson Emerson 4.0K Aug 21 15:45 Downloads
drwxr-xr-x 2 Emerson Emerson 4.0K Dec 15 16:47 Music
drwxr-xr-x 4 Emerson Emerson 4.0K Dec 30 15:55 Pictures
drwxr-xr-x 2 Emerson Emerson 4.0K Dec 15 16:47 Public
drwx------ 6 Emerson Emerson 4.0K Jul 19 23:23 snap
drwxr-xr-x 2 Emerson Emerson 4.0K Dec 15 16:47 Templates
drwxr-xr-x 2 Emerson Emerson 4.0K Dec 15 16:47 Videos
Basic wildcards
The Linux shell allows several types of characters to stand-in, or represent, other characters. Officially, Bash refers to this as pattern matching. More popularly, these are referred to as wildcards. Wildcards allow greater ease and flexibility in finding or specifying files.
For now, we’ll focus on the two most basic wildcards:
- ? (question mark)
- * (asterisk)
? (question mark) wildcard
In patterns, the ? wildcard will match to any one character.
For instance, file?.txt
will match:
- file1.txt
- file9.txt
- fileA.txt
- fileb.txt
- file_.txt
- file .txt
- and any other file that starts with file, ends with .txt, and includes any one character between those strings.
* (asterisk) wildcard
In patterns, the * wildcard will match to any characters, including no character.
For instance, file*.txt
will match:
- file.txt
- file1.txt
- file11.txt
- file141.txt
- file9.txt
- fileAa.txt
- filebin.txt
- file_today.txt
- file of the month.txt
- and any other file that starts with file, ends with .txt, and includes any character, characters, and no character, between those strings.
To understand the utility of this, let’s pair these wildcards with the ls command.
wildcard example 1
Command:
ls recipe?.txt
This will list all files in the working directory that start with recipe, end in .txt, and have one character in between.
wildcard example 2
Command:
ls *.pdf
This will list all files in the working directory that end in .pdf.
wildcard example 3
Command:
ls *Report.od?
This will list all files in the working directory that start with any characters, includes the string Report.od in the middle, and ends with any one character.
There are more wildcards that we’ll discuss later but these two are the most helpful for beginners.
cd command
Now we’ve seen one directory. Let’s look at others.
The cd command allows us to change directories - that is, to navigate to a different directory.
It requires additional arguments (most of the time) to change to the directory we want. Check the tldr entry for cd to see some of the options.
Command:
tldr cd
Let’s start by going up one directory.
Command:
cd ..
Output:
The cd command doesn’t print output, so the only visible output will be the terminal printing the prompt on the next line.
So, to see what changed use the pwd command again.
Command:
pwd
Output:
/home
As expected, we moved up one directory.
Use the ls command to see what’s here.
Command:
ls
Example Output:
Emerson
If you’re working on a system with only one user, you’ll see just the directory for your user name.
Let’s now move down one directory.
Command:
cd Emerson
Use the pwd command again.
Command:
pwd
Output:
/home/Emerson
And we’re back where we started.
Let’s use the - option to move back to the previous directory.
Command:
cd -
Use the pwd command again.
Command:
pwd
Output:
/home
And we’re back up one directory.
Let’s now specify a path of a directory.
Command:
cd Emerson/Pictures/Wallpapers/
Note 1: The directory separator is a forward slash “/”, not a backslash.
Note 2: You can use the TAB key to autocomplete other text besides just a command name. For instance, for the command above, try typing cd Emerson/Pict and then press the TAB
key. The terminal will autocomplete to cd Emerson/Pictures/. If you then type a “W” and press TAB
again, it will autocomplete the rest of the directory name. (Unless you have another directory or file that starts with “the same letters, the preceding autocompletes should work.)
Use the pwd command again.
Command:
pwd
Output:
/home/Emerson/Pictures/Wallpapers
We moved 3 directories down to the location we specified.
The home directory
The directory we started in /home/Emerson has special importance in Linux.
It is called the home directory.
It is the, well, home for many user-specific files.
As the Ubuntu documentation describes:
The home directory is:
- Where your Desktop resides.
- Where your documents, pictures, music, videos, audio, and pretty much everything else can be stored.
- Where your application settings are stored, in hidden files and directories (their names start with a . ) that you should not touch unless you know what you are doing. Eg, /home/username/.thunderbird contains your Thunderbird emails and contacts, /home/username/.mozilla contains Firefox bookmarks, passwords, history, plugins…
- The only place (with the exclusion of removable drives and the /tmp directory) within the Ubuntu file system where a user can freely create/modify/remove files and directories without needing root permissions or the sudo command.
Because of it’s importance there are a few special cases that apply to it when navigating the file system.
cd (without arguments)
The first is that we can navigate to the home directory by using the cd command without any arguments.
To see this, let’s first confirm that we’re stil in the directory we moved to in the last example.
Command:
pwd
Output:
/home/Emerson/Pictures/Wallpapers
Now let’s use the bare cd command to navigate directly to the home directory.
Command:
cd
Use the pwd command again.
Command:
pwd
Output:
/home/Emerson
It’s a quick and simple way to get to the home directory.
tilde expansion
If we want to navigate to a sub-directory of the home directory, we have another useful shortcut available.
Called tilde expansion, it allows us to replace the part of the path for our home directory with a tilde (~).
Instead of typing the command cd /home/Emerson/Pictures/Wallpapers/ we could shorten it with the following:
Command:
cd ~/Pictures/Wallpapers/
Use the pwd command again.
Command:
pwd
Output:
/home/Emerson/Pictures/Wallpapers
Combining tilde expansion with tab autocompletion, you can navigate around the file system with very few keystrokes.
As you may have noticed while working with the cd command, it can be tedious figuring out what files you have, where they are located, and how the directory structure is arranged.
The GUI offers one alternative for navigating visually.
But fortunately, there is another tool that can be used in the terminal to quickly get a sense of the layout and contents of a directory.
tree command
The tree command from Steve Baker displays a visual tree of the directory, it’s subdirectories, and all their content.
It is a helpful tool and can greatly simplify many tasks.
It is, however, not installed by default on most systems.
Installing the tree command
To install tree on Ubuntu:
Command:
sudo apt install tree
Using the tree command
To get started using the tree command, let’s start by checking the tldr entry.
Command:
tldr tree
Then let’s make sure we’re in the home directory to test the command in a familiar context.
Command:
cd
Now let’s start by looking at the home directory to a depth of 1 level.
Command:
tree -L 1
Example Output:
.
├── Desktop
├── Documents
├── Downloads
├── Music
├── Pictures
├── Public
├── snap
├── Templates
└── Videos
That’s not too disimilar to output to the ls -1 command, though it’s a little easier to see the directory structure.
Let’s try again to a depth of 2.
Command:
tree -L 2
Example Output:
.
├── Desktop
├── Documents
│ ├── Articles
│ ├── ProjectX
│ └── Software
├── Downloads
├── Music
├── Pictures
│ ├── Screenshots
│ └── Wallpapers
├── Public
├── snap
│ ├── firefox
│ └── snapd-desktop-integration
├── Templates
└── Videos
Let’s navigate to the Documents directory and see how to view only directories.
Command:
cd ~/Documents
First, we’ll look at the output of the command for this directory to a depth of 1 level.
Command:
tree -L 1
Example Output:
.
├── Articles
├── ProjectX
├── Software
├── Overview.pdf
├── Proposal.odt
└── shopping list.txt
The output includes normal files, if we have any in the directory.
If we’d like to focus on only directories, we can use the -d
command option to only show directories.
Command:
tree -L 1 -d
Example Output:
.
├── Articles
├── ProjectX
└── Software
As you can see tree offers a faster and more intuitive way to get an understanding of a directory structure.
As with many commands, there’s additional functionality that isn’t shown here. To learn more about the tree command, you can read the tldr pages or man pages, or look at our previous post about getting started with the tree command.
Creating and deleting directories
Now that we can navigate and view existing directories, we’ll also want to create some of our own.
mkdir command
The mkdir command from the GNU project makes directories.
Let’s create a test directory to see it in action.
If you’re not already there, navigate to your home Documents directory.
Command:
cd ~/Documents
Next, we’ll use the tree command to confirm there aren’t any existing directories with the name we want to use:
Command:
tree -L 1 -d
Example Output:
.
├── Articles
├── ProjectX
└── Software
Then, we’ll use the mkdir command to create a directory called Test123Directory. We’ll use the verbose option (v
) to see what is happening.
Command:
mkdir -v Test123Directory
Output:
mkdir: created directory 'Test123Directory'
We’ll run tree again to see our changes.
Command:
tree -L 1 -d
Example Output:
.
├── Articles
├── ProjectX
├── Software
└── Test123Directory
We successfully created a new directory.
It’s good to get in the habit of checking documentation, so take a look at the tldr pages for mkdir to see more options for using the command.
rmdir command
If we can create directories, we should also be able to delete them.
The rmdir command from the GNU project removes directories, with the caveat that it only works on empty directories. (Later we’ll see how to remove directories that contain files.)
Let’s try it on the test directory we created in the previous example.
In the home Documents directory delete the Test123Directory
Command:
rmdir -v Test123Directory
Output:
rmdir: removing directory, 'Test123Directory'
Run the tree command to see the changes.
Command:
tree -L 1 -d
Example Output:
.
├── Articles
├── ProjectX
└── Software
We successfully deleted the directory.
Again, it’s good to get in the habit, so take a look at the tldr pages for rmdir to see more options for using the command.
Opening directories in a graphical file manager
Now that we can find our way around the file system via the command line we may occassionally want to work with a directory graphically as well. There is a quick way to open directories in a graphical interface via the shell.
open command (for directories)
As you might expect, the open command from freedesktop.org opens files and directories using the default application for the file type.
Try the following command from the home directory.
Command:
open Documents
This should open the Documents directory in the default graphical file manager. For Ubuntu systems using GNOME desktop from the GNOME project this is GNOME Files (formerly called Nautilus).
Let’s now try it in a different form. First, we’ll navigate to a different directory:
Command:
cd ~/Pictures/Wallpapers/
Then we’ll execute the open command with .
(a period) that tells the shell to run the open command on the working directory.
Command:
open .
Since the current working directory is ~/Pictures/Wallpapers/ the default graphical file manager was opened to that location.
Working with files
Now that we can view, create, delete, and open directories, we’ll also want the same abilities for files.
Caution
Before we look at these next commands, you should use the commands we learned previously to first create a new directory in which to test these commands. To follow along with the examples below, create a new directory named TestABCDirectory in your home Documents directory. This will make it easier to see the effects of the changes we’re making and will reduce the risk of impacting files we don’t want to alter or delete. This is particularly important because we will be deleting files and directories recursively.
After you have created your ~/Documents/TestABCDirectory test directory, we can proceed to learning the next set of commands.
touch command
The touch command can be used for other things, but most often it is used to create files.
To try it, let’s first navigate to the ~/Documents/TestABCDirectory test directory we just created.
Command:
cd ~/Documents/TestABCDirectory
Then let’s create a text file called test123.txt:
Command:
touch test123.txt
Use the ls command to see the result.
Command:
ls -1
Output:
test123.txt
We’ll also run the tree command to see the results it displays.
Command:
tree
Output:
.
└── test123.txt
We successfully created the file.
mv command
Now that we’ve created a file, let’s say we want to move it.
We’ll first create a new subdirectory to move it to.
Command:
mkdir -v Test456Subdirectory
Output:
mkdir: created directory 'Test456Subdirectory'
We’ll run tree again to see our changes.
Command:
tree
Output:
.
├── test123.txt
└── Test456Subdirectory
mv command (to move files)
Now we’ll use the mv command from the GNU project to move our test file into our new subdirectory.
Command:
mv -nv test123.txt Test456Subdirectory/test123.txt
We used the n
(no overwrite) option to prevent any possible overwriting of existing files. It was not a concern in this case since we just created the subdirectory, but it’s a good habit to learn.
We also used the v
(verbose) option to get output from the command to see what it has done.
Output:
renamed 'test123.txt' -> 'Test456Subdirectory/test123.txt'
Note that the output is a little odd because it says the file was “renamed” though really we just moved it. We didn’t do anything wrong - it’s just a quirk of the output to be aware of.
We’ll run tree again to see our changes.
Command:
tree
Output:
.
└── Test456Subdirectory
└── test123.txt
The test file was successfully moved to the subdirectory.
mv command (to rename files)
Now let’s say we want to rename our test file.
We can use the mv command to rename files as well.
First, we’ll navigate to our subdirectory to keep things simple.
Command:
cd Test456Subdirectory
Then we’ll rename our test file to test567.txt
Command:
mv -nv test123.txt test567.txt
Output:
renamed 'test123.txt' -> 'test567.txt'
We’ll run tree to see our changes.
Command:
tree
Output:
.
└── test567.txt
We successfully renamed our test file.
According to tldr pages, the mv command can move or rename files and directories, so the abilities we just used can be used on directories as well.
cp command (to copy files)
At some point we’ll likely also want to duplicate files.
The cp command from the GNU project allows you to copy files and directories.
To try it, first, we’ll navigate to the root of our test directory.
Command:
cd -
And then we’ll run tree to remind ourselves of the state of the test files and directories.
Command:
tree
Output:
.
└── Test456Subdirectory
└── test567.txt
Now, we’ll copy the test567.txt test file from our subdirectory into our root test directory.
We’ll use the i
(interactive) option to prompt us before overwriting of existing files. Again, overwriting is not a big concern in this case since we know the state of the files and directories, but it’s a good habit to learn to avoid unnecessary mistakes.
We also will use the v
(verbose) option to get output from the command to see what it is doing.
While you enter the following command don’t forget to use tab autocomplete to save some typing.
Command:
cp -iv Test456Subdirectory/test567.txt test567.txt
Because we used the verbose option, we got the following output showing us that the copy was succesful.
Output:
'Test456Subdirectory/test567.txt' -> 'test567.txt'
We can also confirm this with the tree command.
Command:
tree
Output:
.
├── Test456Subdirectory
│ └── test567.txt
└── test567.txt
We now have a test567.txt file in both our main test directory and our test subdirectory.
Let’s run the exact same cp command again to see why using the interactive option is helpful.
Command:
cp -iv Test456Subdirectory/test567.txt test567.txt
Output:
cp: overwrite 'test567.txt'?
We are shown a prompt asking if we want to overwrite the existing file.
If we answer n (or any string that does not start with a y) the file will not be overwritten.
Try typing n and pressing Enter to cancel the overwrite.
Let’s try the same again and this time we will overwrite the file.
Command:
cp -iv Test456Subdirectory/test567.txt test567.txt
Output:
cp: overwrite 'test567.txt'?
Type y and press Enter to overwrite the file.
Output:
cp: overwrite 'test567.txt'? y
'Test456Subdirectory/test567.txt' -> 'test567.txt'
The file is overwritten.
Note that when prompted about overwriting the file any string that begins with a y or a Y will result in the file being overwritten.
You can try the copy command again and use the ls -l command before and after to check the file modification times to see the change in the modification time.
You can also use the cp command to simultaneously copy a file and rename the new copy.
We’ll make a small change to our existing copy command to see this.
First' we’ll run tree again.
Command:
tree
Output:
.
├── Test456Subdirectory
│ └── test567.txt
└── test567.txt
Now change the target file name and run the updated copy command.
Command:
cp -iv Test456Subdirectory/test567.txt test890.txt
Output:
'Test456Subdirectory/test567.txt' -> 'test890.txt'
Run the tree command again to see the change.
Command:
tree
Output:
.
├── Test456Subdirectory
│ └── test567.txt
├── test567.txt
└── test890.txt
We successfully copied and renamed a file at the same time.
See the tldr pages for the cp command to learn about more options.
Specifically, note that, the cp command can copy files and directories, so the abilities we just learned can be used on directories as well.
trash vs rm
Since we can create files we’ll also need to be able to delete them.
But before we cover how to do that, we need to address something important.
The command to delete files or directories that comes standard with nearly all Linux distributions is rm. But, as Rob Griffiths points out, the rm command can be dangerous:
Even if you’re brand new to Terminal, I hope someone has given you this valuable advice:
Be very careful when using the rm command to remove files and folders!
The Unix file and folder deletion tool rm is one of the most dangerous commands around. After all, no one likes to obliterate precious files by accident.
With rm it is possible to accidentally delete the wrong files and directories. And when using rm it can be difficult or impossible to recover those files.
As the Ubuntu command line tutorial cautions:
Unlike graphical interfaces, rm doesn’t move files to a folder called “trash” or similar. Instead it deletes them totally, utterly and irrevocably. You need to be ultra careful with the parameters you use with rm to make sure you’re only deleting the file(s) you intend to. You should take particular care when using wildcards, as it’s easy to accidentally delete more files than you intended.
And as Dave McCay puts it:
The rm command can delete files, groups of files, directories, or complete directory trees. That’s why it must be used with caution. Using rm isn’t difficult, but the penalty for failure is high.
When a file is deleted with rm , it is gone. It isn’t moved to the trash. It is obliterated immediately. That doesn’t mean you should avoid using rm . But to use it safely, you need to be aware of what it can do, and ensure you’re using it properly.
Some tools are more dangerous than others, and far less forgiving of mistakes. That’s why there’s never been a movie called The Texas Wrench Massacre. rm isn’t a wrench, it’s definitely a chainsaw.
People use chainsaws all day everyday, and as long as they use one responsibly and mindfully, they’re fine. It’s the same deal with rm . When you pull rm out of your tool bag, you ought to slow down and check, then double-check, your command line.
We think this is a good analogy and helpfully illustrates the power of rm. However, we respectfully disagree with the assertion that users shouldn’t avoid using rm.
We think you should avoid using rm unless it’s exactly what you need.
We think you should avoid using rm in the same way that you should avoid using a chainsaw for most household tasks. You don’t use a chainsaw to slice bread. You don’t use a chainsaw to open cardboard boxes. You don’t use a chainsaw to cut wrapping paper. A chainsaw is too dangerous and powerful of a tool for most tasks. The cost of a mistake is too high. And there are completely suitable alternatives for most tasks.
Yes, people use chainsaws everyday. And every day some people are hurt badly by chainsaws. It would be senseless to use such a dangerous tool without a need to use it. And typically that just isn’t the case with either chainsaws or rm. It is important to know about the rm command, but we don’t recommend making it your day-to-day tool for deleting files.
Leave the chainsaw in the workshop on the shelf for most daily tasks, and use the safer and simpler tools when they work just as well. Bring out the chainsaw only when that is what you need.
Furthermore, even though the rm command may be helpful with some tasks and might be good to learn eventually, we don’t believe it is the tool that new users should focus on.
Instead, we recommend learning and using the trash command for most situations.
trash command
The trash command from Andrea Farncia moves files to the system trash can.
The trash command operates in line with contemporary expectations that files are simply moved to a temporary location where they can be recovered instead of instantly deleted forever. This gives you a chance to see (and potentially restore) deleted files.
It does not come standard on most Linux distributions, so you will likely need to install it.
Installing the trash command
To install trash on Ubuntu:
Command:
sudo apt install trash-cli
Using the trash command
After installing it, you can use the trash command to delete files.
We’ll start by deleting one of the files we created in the previous section.
First we’ll confirm we’re in the correct location.
Command:
cd ~/Documents/TestABCDirectory/
And we’ll run the tree command to see what directories and files are here.
Command:
tree
Output:
.
├── Test456Subdirectory
│ └── test567.txt
├── test567.txt
└── test890.txt
Now, we’ll use the trash command to delete one of our test files.
Command:
trash test890.txt
And we’ll run the tree command to see the change.
Command:
tree
Output:
.
├── Test456Subdirectory
│ └── test567.txt
└── test567.txt
It successfully removed the test890.txt file.
But let’s say we didn’t mean to delete that file.
If we had used the rm command, we’d have a difficult time restoring it, if it was even possible.
But with trash, we can get it back easily.
Command:
trash-restore
Output:
0 2023-09-15 15:47:48 /home/Emerson/Documents/TestABCDirectory/test890.txt
What file to restore [0..0]:
We’ll type 0
and press Enter
, and the file is restored.
Use tree to see the restored file.
Command:
tree
Output:
.
├── Test456Subdirectory
│ └── test567.txt
├── test567.txt
└── test890.txt
We succesfully restored the file.
Let’s say that we instead want to delete our test subdirectory.
Command:
trash Test456Subdirectory
And we’ll run the tree command to see what directories and files are here.
Command:
tree
Output:
.
├── test567.txt
└── test890.txt
It successfully removed the Test456Subdirectory directory and the test567.txt file it contained.
Again, if we want to restore the directory and file we can use the trash-restore command.
Command:
trash-restore
Output:
0 2023-09-15 15:47:48 /home/Emerson/Documents/TestABCDirectory/Test456Subdirectory
What file to restore [0..0]:
Type 0
and press Enter
, and both the subdirectory and file are restored.
Use tree to confirm the result.
Command:
tree
Output:
.
├── Test456Subdirectory
│ └── test567.txt
├── test567.txt
└── test890.txt
We successfully restored both the directory and file.
One thing to note with the trash command is that since it doesn’t permanently delete files, they remain on your system taking up space until you delete them permanently.
If you want to remove those files, you have several options. (See the tldr pages for trash to see some additional options.) We’ll look at permanently deleting files based on how long they have been in the trash, since it seems probable that the older files are less likely to be needed again.
A note of caution: This step will permanently delete files. Be sure of what you are removing before proceeding and skip this step if you are uncertain.
You’ll use a long span and delete files that have been in the trash longer than 120 days.
Command:
trash-empty 120
rm command
The rm command from the GNU project removes files or directories and comes standard with nearly all Linux distributions, but, as discussed above, it can be dangerous because it’s easy to delete the wrong thing and it can be difficult or impossible to recover files.
If you are going to use the rm command, it usually makes sense to use the i
(interactive) option to see prompts before files are deleted and the v
(verbose) option so that you are made aware of what the command has done.
As mentioned above, we recommend using trash instead of rm whenever possible.
aliasing the rm command
While the rm command itself can be dangerous, some suggested strategies for aliasing rm are also dangerous. If you want to avoid accidental use of rm, alias to a different name than rm so you don’t create a dangerous habit, or consider aliasing to an explanatory echo command.
Text editors
Let’s now look at how to view and edit text files. You’ll use a text editor to do that, and many Linux distributions offer several options. We’ll look at a few of the more common ones:
- gedit
- nano
- Vim / Neovim
We’ll create another test file in our test directory so that we don’t unintentionally alter another file.
First, change directories to the test directory we made in a previous step.
Command:
cd ~/Documents/TestABCDirectory/
And we’ll run the tree command to see what directories and files are here.
Command:
tree
Output:
.
├── Test456Subdirectory
│ └── test567.txt
├── test567.txt
└── test890.txt
Create the new test file with the touch command.
Command:
touch testABCfile.txt
Run the tree command to see the new file.
Command:
tree
Output:
.
├── test567.txt
├── test890.txt
└── testABCfile.txt
Now we have a blank test document we can view and alter.
gedit text editor
The first text editor we’ll look at is gedit from the GNOME project. It will likely be the most familar because it features a simple GUI.
It is easy to work with and available on many Linux distributions.
Let’s use it to open our test file:
Command:
gedit testABCfile.txt
Once it opens you should see a blank page.
If you have used a graphical text editor before the interface is likely familiar.
You can type a few words, save the file, and close it in the expected way.
Let’s try that by adding a line of text to our test file:
Hello World
And then save and exit.
nano text editor
The next text editor we’ll consider is nano from the GNU Project. The interface might require a little familiarization because it is text-based and you interact with it within the command line.
It is somewhat easy to work with and available on many Linux distributions.
Let’s use it to open our test file:
Command:
nano testABCfile.txt
You’ll see a mostly blank page except for the “Hello World” text we added near the top and a partial list of commands at the bottom.
This requires a little effort to learn, but there are a few things that are helpful to know at the beginning:
CTRL
+ G
opens the nano help menu.
CTRL
+ X
closes the help menu.
CTRL
+ S
saves the file.
CTRL
+ X
exits nano.
You can refer to the overview of nano’s shortcuts to find additional features.
Let’s add another line of text to our test file.
Enter a second line of text below the first line:
Hello World
Hello Again
And then press CTRL
+ S
to save and CTRL
+ X
to exit.
Vim / Neovim
The last text editors we’ll mention in this post are Vim and Neovim. Learning Vim or Neovim will require some effort and is beyond what we’ll cover in this post. Here we’ll just introduce them and cover a few key details.
Vim from Bram Moolenaar, like nano, is a command-line text editor.
Neovim from the Neovim team is a command-line text editor based on Vim.
For now, it’s just important to know that:
- Vim and Neovim are text editors that are largely compatible with one another.
- You’re likely to find Vim on almost any Linux system.
- They both have a bit of a learning curve and most users don’t find them intuitive at first.
- Consequntly, you might find yourself unintentionally in one of them. So, it’s helpful to know how to exit them, even if you don’t plan to use them.
- There are helpful resources for if/when you’d like to learn more about them.
How to exit Vim / Neovim
It may seem strange to need to cover this, but exiting Vim is so non-intuitive that many new users feel trapped. Consequently, questions asking how to exit Vim are very popular on StackOverflow.
The basic sequence to quit Vim without saving is:
Esc
:
q
!
Enter
And the basic sequence to save and quit Vim is:
Esc
:
w
q
Enter
Learning more about Vim / Neovim
If you decide to learn Vim or Neovim there are numerous resources available We’ll highlight two:
- The Interactive Vim Tutorial is exactly what it sounds like and provides a guided learning path.
- In Vim Adventures you can learn Vim while playing a game.
open command (for files)
As mentioned above, the open command can also open files.
Let’s use it to open our test file.
Command:
open testABCfile.txt
It will open the file with your default text editor, which is likely gedit.
Getting System Info
There’s one more tool worth mentioning that can be helpful for answering questions you might have as you get started.
neofetch command
The neofetch command from Dylan Araps is a “CLI tool to display information about your operating system, software and hardware.” according to tldr pages.
When you have a question about your system, this tool provides a lot of information in a compact and attractive format. It is an excellent place to start for many system questions.
Installing neofetch
On Ubuntu, neofetch can be installed through the package manager.
Command:
sudo apt install neofetch
Using neofetch
And using neofetch is simple. You just run the neofetch command to see information about your system.
Command:
neofetch
Example output:
.-/+oossssoo+/-. Emerson@desktop
`:+ssssssssssssssssss+:` ------------
-+ssssssssssssssssssyyssss+- OS: Ubuntu 22.04.3 LTS x86_64
.ossssssssssssssssssdMMMNysssso. Host: Altair 8800
/ssssssssssshdmmNNmmyNMMMMhssssss/ Kernel: 6.2.0-32-generic
+ssssssssshmydMMMMMMMNddddyssssssss+ Uptime: 16 days, 12 hours, 47 mins
/sssssssshNMMMyhhyyyyhmNMMMNhssssssss/ Packages: 921 (dpkg), 6 (flatpak), 15 (snap)
.ssssssssdMMMNhsssssssssshNMMMdssssssss. Shell: bash 5.1.16
+sssshhhyNMMNyssssssssssssyNMMMysssssss+ Resolution: 3200x1800
ossyNMMMNyMMhsssssssssssssshmmmhssssssso DE: GNOME 42.9
ossyNMMMNyMMhsssssssssssssshmmmhssssssso WM: Mutter
+sssshhhyNMMNyssssssssssssyNMMMysssssss+ WM Theme: Adwaita
.ssssssssdMMMNhsssssssssshNMMMdssssssss. Theme: Yaru-viridian-dark [GTK2/3]
/sssssssshNMMMyhhyyyyhdNMMMNhssssssss/ Icons: Yaru-viridian [GTK2/3]
+sssssssssdmydMMMMMMMMddddyssssssss+ Terminal: gnome-terminal
/ssssssssssshdmNNNNmyNMMMMhssssss/ CPU: 12th Gen Intel @ 5.500GHz
.ossssssssssssssssssdMMMNysssso. GPU: Intel HD Graphics
-+sssssssssssssssssyyyssss+- Memory: 5162MiB / 15558MiB
`:+ssssssssssssssssss+:`
.-/+oossssoo+/-.
Cleaning up our test files
Now that we have worked through the examples in this post we’ll remove the test files and directories we created.
We’ll navigate to the directory containing our test directory.
Command:
cd ~/Documents
And we’ll run the tree command to see what’s there.
Command:
tree -L 1
Example Output:
.
├── Articles
├── ProjectX
├── Software
├── Overview.pdf
├── Proposal.odt
├── shopping list.txt
└── TestABCDirectory
Now we’ll use the trash command to move the test directory to the trash.
Command:
trash TestABCDirectory
Run tree again to see the results.
Command:
tree -L 1
Output:
.
├── Applications
├── _landing
├── Overview.pdf
├── Proposal.odt
└── shopping list.txt
We successfully moved our test files and directories to the trash.
Conclusion
We’ve covered the basics to get started using Bash and the Linux shell. With the commands covered in this post you can already accomplish quite a lot.
Now you can learn more as your needs or interests dictate. And if you want to learn about Bash and the Linux Shell generally, review our Bash and the Linux Shell topic page.