Skip to content
Go back

Ubuntu & Bash tutorial & basic utilities

By SumGuy 20 min read
Ubuntu & Bash tutorial & basic utilities
Contents

An introduction to the CLI (Command Line Interface) and Bash on Ubuntu Linux aka a bash tutorial

The Basics

The default shell that is installed on Ubuntu Linux is bash. Alternatives exist, but they’re beyond the scope of this tutorial (check our post here for more info on how to isntall a better alternative to bash called Zshell or zshcheck our post here for more info on how to isntall a better alternative to bash called Zshell or zsh). Bash is available on almost all Linux distributions, so this tutorial will work on most Linux distributions as well.

What is a shell? Simply put, the shell is a program that takes your commands from the keyboard and gives them to the operating system to perform. In the old days, it was the only user interface available on a Unix computer. Nowadays, we have graphical user interfaces (GUIs) in addition to command line interfaces (CLIs) such as the shell. Bash is the most popular shell application for Linux, and is the default on Ubuntu and hundreds of other Linux distributions, older macOS releases, and even Windows via WSL.

The basics are:

Instead of typing cd ~/myfolder1/ you can just type cd ~/my and it’ll either autocomplete fully or if there are still more folders (like my234 and myfolder1), it’ll show you your options. You can enter multiple commands by separating them with “;” or “&&”. ; allows commands to run one after another, && runs next command only if first succeeds. For clarity, we will focus only on single commands.

Bash and Linux in general is case sensitive. That means you can have new_folder, New_folder, NEW_FOLDER, and new_Folder all in the same directory. If the computer says a file or folder doesn’t exist, you should check to see if you forgot to capitalize something. This is another good use of tab complete!

The gist of it is that a command takes in arguments/parameters, so you enter your command, add a space, add your arguments. An argument CANNOT HAVE SPACES. A space means that the argument is done and you’re putting in another argument. To circumvent this, you have two options:

Here are the basic things that you’ll need to know how to do to get around.

Commonly Used Commands

These are the commands you’ll actually type every day. Each one gets what it does and what it looks like when you run it.

man

Retrieves the information in the manual about a command and displays it as text on your screen. If you only remember one command out of this whole tutorial, make it this one.

Terminal window
man ls

Page-up/down or the arrow keys browse, q quits, / searches.

ls

Lists all the files and folders in the current directory. Commonly launched with -lsah for better output formatting.

Terminal window
ls Documents
text.txt
ls -lsah Documents
total 3
0 drwxr-xr-x+ 76 username group 2.5K Apr 19 18:52 .
0 drwxr-xr-x 6 root admin 204B Dec 24 01:01 ..
8 -r-------- 1 username group 7B Nov 10 20:41 text.txt

cd

Changes directory. To go up one, it’s cd .. (two periods). cd with no parameters sends you to your home folder. ~ also expands to your home directory, and cd - returns you to your previous working directory.

Terminal window
cd ..
cd my_folder

rm

Deletes files. Will delete folders recursively too with the -r option. The -f option forcefully removes files without warning.

Terminal window
rm my_file.txt
rm -r my_folder
rm -rf my_folder # forcefully removes a directory and its contents

A common meme is telling people to run rm -rf /. Don’t. And the “helpful” follow-up when that gets refused is worse:

Terminal window
rm --no-preserve-root -rf / # recursively wipes your entire filesystem, don't

rmdir

Removes an empty directory. It refuses to touch non-empty ones, which saves you from nuking a folder you forgot had files in it.

Terminal window
rmdir test

cp

Copies files and directories. Use -R for copying directories.

Terminal window
cp my_file.txt my_file_copy.txt
cp my_file.txt directory/my_file.txt
cp -R my_folder my_folder_copy

mv

Moves files and folders. Also the way to rename things on the command line.

Terminal window
mv my_file.txt this_subdirectory/my_file.txt
mv my_old_foldername my_new_foldername

pwd

Prints what folder you’re in. Sort of useful, though your shell prompt probably shows it already.

Terminal window
pwd
/home/username

!!

Re-runs the last command. Can be combined with other commands.

Terminal window
pwd
/home/username/desktop/mydir
cd ..
pwd
/home/username/desktop
!! # re-runs "cd .."
pwd
/home/username

sudo

Runs a command as a different user, root by default. Does not work with cd.

Terminal window
mkdir folder
mkdir: cannot create directory 'folder': Permission denied
sudo mkdir folder
[sudo] password for user:

Enter your password and the permission problem goes away. Pair it with !! to retry the command you just fumbled:

Terminal window
sudo !!

mkdir

Makes a directory.

Terminal window
mkdir folder

chmod

Changes file permissions (read, write, execute). Use + to add a permission and - to remove it.

Terminal window
chmod +x myprogram
./myprogram
chmod -x myprogram
chmod 777 filename.txt # allow anyone to edit

nano

The easiest command line text editor. With no arguments it opens empty, like launching notepad.exe without a file. Ctrl+O saves, Ctrl+X exits.

Terminal window
nano mytextfile.txt

passwd

Changes your password. Often needs to be run as root, or preceded by sudo.

Terminal window
passwd
Changing password for user
(current) UNIX password: guest
Enter new UNIX password: hunter2
Retype new UNIX password: hunter2

Your typing isn’t echoed back, so those prompts will look empty while you type. They’re filled in above just to show the flow.

cat

Concatenates two (or one) files, or prints everything in a file. Not great for reading long files, use less for that.

Terminal window
cat my_file.txt

Prints the first 10 lines of a text file.

Terminal window
head my_file.txt

tail

Prints the last n lines of a text file. Super useful for log files. With -f it holds the file open and streams new lines in real time.

Terminal window
tail -n 10 -f logfile.txt

less

Lets you view a text file without editing it. Can also follow log files with +F, similar to tail -f.

Terminal window
less my_file.txt
less +F logfile.txt

grep

Searches through a file, or the output of a program, using regular expressions. Search every file in a folder with -r.

Terminal window
grep 'Error:' my_file.txt
grep -r 'find me' my_directory/

tar

Extracts files from tar archives, and creates them. The options you’ll see most:

Terminal window
tar -xzf system_backup_2016_04_07.tar.gz

Modern versions detect the compression format on their own, so -xf (extract file) and -cf (create file) are usually all you need. If the flags still won’t stick, this cheat sheet is the classic.

touch

Creates an empty file with the given name if it doesn’t exist. Also updates the timestamp on an existing file without modifying its contents.

Terminal window
touch foo.bar

top

Terminal-based interface for watching running processes.

Terminal window
top

ln

Creates links (shortcuts) in the filesystem. In general always use -snf. Trust me.

Terminal window
ln -snf /opt/foo /usr/bin/bar

/usr/bin/bar now links to /opt/foo, and it’s transparent to the operating system.

screen

screen lets you run multiple login sessions in the same terminal. Say you want to run a long process: launch it inside screen, detach it, and come back to the same process later.

Inside a screen session, Ctrl+A then Ctrl+D detaches it (puts it in the background). To reattach, run screen -r. With one session you land straight back in, otherwise you have to name the session you want.

Terminal window
screen bash
screen -r
screen -ls
There are screens on:
767.ttys000.localhost (Detached)
844.ttys002.localhost (Detached)
2 Sockets in /var/some/folder/random/T/.screen.
screen -r 767.ttys000.localhost

whoami

Prints the currently logged in user.

Terminal window
whoami
john

whereis

Prints the location of a command, plus its source and man page if it can find them. It searches a fixed list of standard directories.

Terminal window
whereis echo
/bin/echo

which

Prints the location of a command the way your shell resolves it, by walking your $PATH. When whereis and which disagree, which is the one telling you what actually runs.

Terminal window
which echo
/usr/bin/echo

echo

Outputs text to the command line. Useful when writing shell scripts.

Terminal window
echo "hello world"
hello world

kill

Asks a process to terminate. By default it sends SIGTERM (signal 15), which asks the process to clean up after itself and exit.

Terminal window
kill 4815

If the process ignores that, kill -9 sends SIGKILL, which a process cannot catch or ignore. It forcibly terminates almost anything, at the cost of no cleanup.

Terminal window
kill -9 4815

killall

Terminates processes by name instead of by process ID.

Terminal window
killall firefox

file

Shows you the file type, regardless of what the extension claims.

Terminal window
file my_file.txt
my_file.txt: UTF-8 Unicode text

date

Shows the current date and time in text form.

Terminal window
date
Tue Apr 19 15:31:54 CDT 2016

ps

Displays information about running processes. Different from top in that ps gives you one snapshot, which means you can pipe it into other commands.

Terminal window
ps -ef
ps -ef | grep firefox

apropos

Finds commands that do a given task. It returns every command whose man page mentions your search term, which is how you track down a tool when all you know is what you want it to do. Same as running man -k.

Terminal window
apropos remove
colrm (1) - remove columns from a file
cut (1) - remove sections from each line of files
...
apropos concat
cat (1) - concatenate files and print on the standard output
cat (1p) - concatenate and print files
eval (1p) - construct command by concatenating arguments
...

alias

Creates custom shortcuts for commonly used programs or parameters.

Terminal window
alias lcolor='ls --color=auto'

Now lcolor does the same thing as ls --color=auto, but shorter. Put your aliases in ~/.bashrc to keep them between sessions.

env

Lists (or sets) environment variables.

Terminal window
env
HOSTNAME=hostname.abcdefg.com
SHELL=/bin/bash
...

The Filesystem in a Nutshell

“Everything is a file”. In Linux, everything is treated as a file, even your devices.

Unlike Windows and DOS, Unix systems and Linux do not have drive names. Your thumb drive will be mounted as a “folder” on Linux, Instead of being F:\ on Windows, it would be /media//my_thumbdrive, assuming that is the device name on linux. On Ubuntu, drives are usually mounted in the /media folder under your username. All your shared folders in Virtualbox will show up there, but not under your username.

/home Where your user files are stored (equivalent of C:\Users) /media Where drives are mounted (In Ubuntu) /bin Where system executables are stored (almost the equivalent of system32) /lib Where the system stores the library files (like the .dll’s in system32) /usr/bin Where extra stuff you install is stored, like python (almost equivalent of C:\Program Files)

/etc Where configuration files for various programs and network services are stored

(Equivalent to where C:\Program Files\ApplicationName files are stored)

/dev Where all the systems devices can be found. Since everything is a file in Linux, every hardware device also has a corresponding file under /dev

/tmp Where temporary files are stored (This is wiped upon reboot, unless configured otherwise)

/var Variable files, files whose content is expected to continually change during normal operation of the system, such as logs, spool files, and temporary email files. /proc Where you can query the hardware for information e.g. cat /proc/cpuinfo Your home folder location can be referred to as ~. So instead of typing out /home/me, you can just type ~, and it’ll resolve to be the same path.

And that’s about the extent you need to know, and probably more so to be honest. /home//bin is a good place to store any shell scripts or whatnot that you want to run from any folder. Which brings us to our next topic…

Running Your Own Scripts

Earlier in the table of commands, I mentioned the chmod command. Files created by you will almost always be only read write permission level, which is great from a security standpoint. However, say you want to run a python script. You* could* do python myscript.py but that’s cumbersome. Instead, let’s do it the Linux Way™.

The Header Comment

The official name is the “shebang”, but in this guide I’ll call it the header comment, it’s a special type of comment you put at the top of a script in a Linux environment to tell the shell what  program to execute your program with. For a python script, you do this: #!/usr/bin/env python If we were writing a perl script, we would do #!/usr/bin/env perl If you were to write a bash script we would do: #!/usr/bin/env bash What it’s telling the shell to do is to look in the environment settings of the linux install, figure out where python is installed, and then run the rest of the source code through the python executable. This method has the benefit of not only being portable (python might not be installed in the same place on all linux systems), it’s also super easy to remember what to write each time if you deal with multiple programming languages.

Linux Doesn’t Care About File Extensions

With the header comment written, we now don’t have to worry about putting .py at the end of the filename anymore. You could name it “mypythonscript.jpg” if you wanted to, the data inside it is the same, and Linux just looks for that header comment, so it really doesn’t matter. It’s super nice to have no extension though, especially if you run the script a lot. You’ll just have to have your python scripts organized in a separate folder if you’re going to start foregoing extensions, hard to tell file types apart with no extension. The ‘file’ command can be used to identify which type of file a file is if you prefer to have no extensions.

Running Your Script

The first thing you have to do is mark it as executable. To do so, we’re going to use our trusty chmod command. We want to mark it as executable, so we’re going to use the u+x argument to add executable permissions to the file, This tells Linux to change the file mode to executible by the user only. chmod u+x mypythonscript.py Now, our script is executable. You can verify this by running ls, and it will now be green. Green means an executable file. To run it, we’re going to do

Terminal window
./mypythonscript.py

This is a security measure put in place by Linux so that you can be sure you are executing the file within the current directory, imagine if someone placed a malicious executable named ls in a folder, and you ran ls, and instead of executing the one in /bin, it ran the malicious one in your current folder? It wouldn’t be good.

In Linux, a single period is your current directory, and two periods is the parent directory. So ./mypythonscript.py

is really /home/my_username/my/full/path/name/mypythonscript.py If you have a script you do want to run from anywhere, put it in your bin folder in your home folder (~/bin). If you want to make that script or executable available for all users on the system, place it in /usr/local/bin.

Cancelling a Process in the Terminal

To stop a process, hit CTRL+C. This sends SIGINT to the current program and is the standard way to cancel a running process. CTRL+D sends an EOF (end-of-file) to the program’s input, which causes programs that read from stdin (like an interactive Python or bash prompt) to exit gracefully, but it does not terminate arbitrary processes.

Previously, it was mentioned you can run multiple commands by either separating them with “;” or “&&”. The difference is that if you separate with a semicolon, all commands run sequentially regardless of whether previous commands succeeded or failed; For example if I run the following:

Terminal window
./my_script.py; cp script_output backup/script_output; ./my_script2.py

If my_script.py has an error and fails, the copy command and my_script2.py will still run. Each command is independent.

Alternatively, if you use && to run multiple commands:

Terminal window
./my_script.py && cp script_output backup/script_output && ./my_script2.py

Now, if my_script.py encounters an error (exits with a non-zero status), the remaining commands will not run, && only continues to the next command if the previous one succeeded. Choose the method of running multiple commands wisely. Personally I like using the && method better simply because it stops the chain if something goes wrong.

To paste into the terminal, you must use CTRL+SHIFT+V. CTRL+V will not work to paste. Similarly, copying in the terminal must be CTRL+SHIFT+C.

Be careful when pasting commands into the terminal! If there’s a new line at the end of the command, it’ll automatically run the command!! (like if you hit enter after typing a command).

Multiline commands can be separated with \

Example:

Terminal window
cd \
/var/log

Is the same as cd /var/log, only split over two lines. Useful for long commands.

Package Manager

No linux tutorial would be complete without an introduction to the package manager. This is a unique feature of linux, it allows you to install, update, and remove any piece of software on your computer. The syntax is very simple too. All package management must be run as root, or with “sudo” before it.

Apt, the Advanced Package Tool

CommandWhat it doesExample
sudo apt updateRefreshes the list of available software. If a security update for Python got released yesterday, update is how your machine finds out about it.sudo apt update
sudo apt upgradeInstalls newer versions of the software you already have, applying the patches that update found.sudo apt upgrade
sudo apt installInstalls a package.sudo apt install python3
sudo apt removeRemoves a package.sudo apt remove vim
aptitudeLaunches a text-based (ncurses) package manager, good for browsing and searching for packages. Runs fine without root, but you can’t install anything unless you do. Q quits.sudo aptitude

Older tutorials will use apt-get, which has since been superseded by Apt. Apt-get will still work fine, but apt is the new standard, and it has some nice improvements.

To easily search for packages in the repository, you can use Synaptic Package Manager, or you can

just google “how to install x on ubuntu” and you’ll find the package name. You can try guessing a package name, but you might not always be successful.

Pip is also directly accessible through the command line for python. Just run sudo -H pip install

Python Virtual Environments

On your own machine, you have full root access, but on a work machine you most definitely will not. Having a python virtual environment allows you to install as many python packages with pip as you want, without needing to run sudo pip install.

A good rule of thumb is to create a virtual environment for every project, separately, to separate dependencies from one environment to another.

An easy way to create virtual environments is to globally install a pip package called virtualenvwrapper.

To set up a virtual environment of python, create a directory in your home folder that you want the virtual environment to live in. Then run the following commands to create the virtual environment. sudo pip install virtualenv

virtualenv pythonv To make the python virtual environment your default python environment in your session, simply run source /path/to/pythonv/bin/activate Now when you run which python it will output /path/to/pythonv/bin/python.

Note that this is a temporary change, Closing the terminal or logging out will revert this change. Adding this to your ~/.bashrc file will execute it upon login, or you can set it as an alias in your bashrc.

Shell Piping and Redirecting IO

There are four redirection and pipe characters you’ll reach for constantly:

CharacterWhat it doesExample
>Redirects output to a file, overwriting whatever was there.man -k search > man_output.txt
>>Redirects output to a file and appends instead of overwriting.man -k find >> man_output.txt
|Takes the output of process A and feeds it in as the input to process B.cat man_output.txt | grep "fast"
&>Redirects both standard output and standard error to the same place.cat file.txt &> output.txt

In Linux, you have two main pipes, Standard Output (stdout, all your normal output of things that are printed to the screen), and Standard Error (stderr, when something doesn’t work right, Error on line 2, ‘;’ expected)

stdout is numbered pipe 1, and stderr is numbered pipe 2. By default, > is actually 1>, redirecting standard output. If we wanted to redirect standard error, we would do 2>. 2>> will append, just like >> does. If we want to redirect both error and output, we can do &>.

This post and ubuntu / Linux / bash intro tutorial is based on work by mcvittal of reddit who licensed it under the WTFPL, Do What The Fcuck You Want To Public License. This post is here for archival and informational purposes.


Share this post on:

Send a Webmention

Written about this post on your own site? Send a webmention and it'll show up above once verified.


Previous Post
Enable WebGL on Chrome or Firefox
Next Post
Why You Should Switch to ZShell (zsh)

Discussion

Powered by Garrul . Sign in with GitHub or Google, or post anonymously.

Related Posts