Home Articles Categories Series
Pythonise Just now
Recommended learning

A gentle introduction to Bash | Learning Linux Pt. 3

Launching a Bash terminal, accessing the manual, navigating the file system and the basics of shell scripting

Article Posted on by in Linux
Julian Nash · 2 years ago in Linux

The "Bourne-again shell", more commonly known as just "Bash" is the default shell/command interpreter that comes with most distributions of Linux & Mac OS and is part of the GNU software suite of tools.

A shell (in computing terms) is a user interface for interacting with a computers services, accepting text input from a user, performing an action and typically returning some kind of feedback. They also allow us to do things like connect remotely to another machine over the network and interact with it, known as Secure shell (SSH).

Shells aren't exclusive to Linux or Unix-like operating systems and you'll find the Command prompt & Powershell on Windows machines, Bash on Mac (albeit an older version), along with a several alternative command interpreters including C shell (Csh), Friendly interactive shell (FISH) & Z shell (Zsh) to name a few. We'll be sticking with Bash throughout this series as it's one of the more popular shells and ships with most Linux distros.

You'll often hear the term "shell" being referred to as the "terminal" or "CLI" (command-line interface). We'll be using "shell" or "terminal" throughout this series so thought to point it out.

In addition to being a command processor that takes input from users and does our evil bidding, Bash is also a fully fledged command language, meaning we can use it to write "Shell scripts" which we can then execute.

We'll cover shell scripting later in this series, but it's important to point out now that any commands we cover throughout this series can be written in a file called a shell script file and executed! Pretty cool right?

In this guide, you'll simply be learning how to open up a shell, enter some basic commands and creating/executing a small shell script. We're going to cover individual commands and explore many of the software, tools and libraries found on most Linux machines in their own separate guides.

Let's get started by opening a new terminal and entering some basic commands.

Opening a terminal

Launch a terminal by right clicking on the desktop and selecting Open Terminal or searching for "Terminal" and clicking on it. You should be greeted with a window that look similar to this:

New Bash Terminal

In the terminal window you'll notice a single line of text is being displayed. This is called the "prompt" and is used to provide some visual feedback about the current user logged into the terminal, the name of the machine, the current directory and finally a $ symbol.

Terminal prompts vary between distros but typically follow this pattern of username@machine: /path/to/current/directory $.

The $ indicated where you enter your commands, so let's go ahead and do that!

Basic bash commands

The Bash terminal accepts text commands, which are executed on hitting the return key on your keyboard.

Let's take a flying tour of the Linux file system and direcrory structure, but before we do, let's quickly cover commands and arguments.

Commands and arguments

Commands are our way of telling our system that we want to do something, but they sometimes need instructions on what to do, where to go and how to do it! Computers like to do exactly what we tell them so we need to be explicit and give them our guidance, they can't read our minds... Yet.

If a command is like telling someone to jump, then an argument can be compared to telling them how high, or for how long (and the good thing about computers, is that we don't have to give them a reason!)

We provide arguments to commands by simply entering the command, followed by a space, then the argument (or arguments), for example:

cd ~

This command will "Change directory" to your home directory.

Just like you would use a mouse pointer to double click on directories to enter them and click the back button to exit them, we can do the same with the cd command.

cd stands for change directory, which we can combine with an argument for where we want to move to.

Opening a terminal will launch you into your home directory by default, indicated by the ~ symbol next to your prompt. Your home directory on Linux is just like home directory of any other operating system and is a good place to store your files, scripts, images etc.

Before we use the cd command, let's find out exactly where we are.

Go ahead and enter the following command:


You'll see something similar to:


pwd stands for "Present working directory" and returns the current directory you're in, represented by a full "path" from the root of the system.

The root of the system is indicated with a leading / at the start of the path, with any subsequent directories being separated with a / in-between.

Linux uses a different system for structuring directories compared to Windows and we'll be exploring it in more detail in the next part of this series.


If at any point you'd like to learn more about any of the Bash commands or executables, you can read the Linux manual!

To access the manual, we run the man command followed by the name of the command or executable we'd like to learn about, for example:

man pwd

This returns:

       pwd - print name of current/working directory

       pwd [OPTION]...

       Print the full filename of the current working directory.

       -L, --logical
              use PWD from environment, even if it contains symlinks

       -P, --physical
              avoid all symlinks

       --help display this help and exit

              output version information and exit

       If no option is specified, -P is assumed.

       NOTE: your shell may have its own version of pwd, which usually supersedes
       the version described here.  Please refer to  your  shell's  documentation
       for details about the options it supports.

       Written by Jim Meyering.

You'll notice we are presented with the name of the command, a synopsis (how to use it) and a description that explains some of the arguments we can use with it.

The manual is a great tool and we definitely recommend using it!

Now that we know exactly where we are, let's learn more about the cd command.

Changing directories

To use the cd command, we need to provide it with an argument, instructing it where we want to end up.

We can provide cd with a few dirrefent types of arguments:

  • A single directory name that's in the same directory as we are, for example:
cd hello

Will change us into the hello directory, providing hello is in the same directory as us.

  • A full path to a directory from the root of the system
cd /home/julian/hello

Will also change us into the hello directory, providing we supply a full and existing path

  • A relative path from our current location
cd hello/world

Will take us to the world directory, assuming we run this command from the directory containing hello.

If we try and cd into a directory that doesn't exist:

cd ghost

We get an error message like the following:

-bash: cd: ghost: No such file or directory

We can also use a few special characters & commands to get us somewhere fast, including:

  • cd - cd without any arguments will always take you to your home directory
  • cd . - Will leave you in the current directory
  • cd ~ - Change to the home directory
  • cd ~username - Another way to change to the home directory
  • cd .. - Go up one directory
  • cd / - Change to the root of the system
  • cd - - Go back to the previous directory

Let's jump to the root directory of the system. Enter the following command:

cd /

You'll notice your prompt has changed slightly and ~ has been replaced with /, indicating the new directory we're currently in.

julian@jnwt: /

We can also see our current location by running the pwd command, go ahead and run it:


You'll see:


Knowing what directory we're in is all well and good, but we also need a way to display the contents of the directory!

We'll come back to the cd command in just a moment, but for now, let's learn more about how we can use the ls command to "list" the contents of a directory.

Listing a directories contents

The most simple way to list a directories contents is with the ls command on its own. Go ahead and give it a try:


Assuming you're following along and you're in the root directory, you'll see something similar to the following:

bin  boot  data  dev  etc  home  init  lib  lib64  media  mnt  opt  proc  root  run  sbin  snap  srv  sys  tmp  usr  var

Welcome to the root of your Linux system! You'll see we have several directories here which we'll be covering in the next part of this series.

The ls command as you've seen, will list the contents of the current directory, and on its own might be enough for what you need, but what about when we want some more information about each file or directory listed?

Using a mouse, we could quite easily right click on the file or directory and view some of the properties such as the filesize, date it was created, owner, permissions etc.

To see more information about the contents of the directory we're listing, we can combine ls with an option to get some more details.

Run the following command:

ls -l

You'll see something very similar to this:

total 112
drwxr-xr-x  1 root root   4096 Jan  2 17:58 bin
drwxr-xr-x  1 root root   4096 Jul 25  2018 boot
drwxr-xr-x  1 root root   4096 Jan  3 11:31 data
drwxr-xr-x  1 root root   4096 Mar 21 16:21 dev
drwxr-xr-x  1 root root   4096 Mar  6 00:30 etc
drwxr-xr-x  1 root root   4096 Jan  2 17:58 home
-rwxr-xr-x  1 root root 112600 Jan  1  1970 init
drwxr-xr-x  1 root root   4096 Jan  2 18:22 lib
drwxr-xr-x  1 root root   4096 Jul 25  2018 lib64
drwxr-xr-x  1 root root   4096 Jul 25  2018 media
drwxr-xr-x  1 root root   4096 Mar  4 17:53 mnt
drwxr-xr-x  1 root root   4096 Jul 25  2018 opt
dr-xr-xr-x 22 root root      0 Mar 14 11:06 proc
drwx------  1 root root   4096 Jan  3 22:55 root
drwxr-xr-x  1 root root   4096 Mar 22 14:02 run
drwxr-xr-x  1 root root   4096 Jan  9 21:59 sbin
drwxr-xr-x  1 root root   4096 Jul 19  2018 snap
drwxr-xr-x  1 root root   4096 Jul 25  2018 srv
dr-xr-xr-x 12 root root      0 Mar 14 11:06 sys
drwxrwxrwt  1 root root   4096 Mar 26 23:53 tmp
drwxr-xr-x  1 root root   4096 Jul 25  2018 usr
drwxr-xr-x  1 root root   4096 Jul 25  2018 var

The addition of the -l option has told the ls command to return a "long listing format", revealing more information about the contents of the directory.

We'll dive into what each of the individual columns mean in the ls command feature of this series, but for now, just know that you're seeing the permissions, number of links, owner, group, filesize, date modified and the name of the file/directory, in that order.

Let's continue on our quick tour of Linux and take a look at some more options for the cd command.

Seeing as we're in the root of our machine, let's use cd and ls to take a peek at some of the directories and files.

Move into the bin directory with the following:

cd bin

You should see your prompt change to include /bin.

The bin directory contains the executable files that must be available to attain the minimum functionality of the system, such as booting and repairing the machine, along with many other ready to run programs, tools and binaries.

Go ahead and run ls to take a look at the contents of bin:


You'll see:

bash                cp             kbd_mode    netcat         readlink                        tar
btrfs               cpio           kill        netstat        red                             tempfile
btrfs-debug-tree    dash           kmod        networkctl     rm                              touch
btrfs-find-root     date           less        nisdomainname  rmdir                           true
btrfs-image         dd             lessecho    ntfs-3g        rnano                           udevadm
btrfs-map-logical   df             lessfile    ntfs-3g.probe  run-parts                       ulockmgr_server
btrfs-select-super  dir            lesskey     ntfscat        sed                             umount
btrfs-zero-log      dmesg          lesspipe    ntfscluster    setfacl                         uname
btrfsck             dnsdomainname  ln          ntfscmp        setfont                         uncompress
btrfstune           domainname     loadkeys    ntfsfallocate  setupcon                        unicode_start
bunzip2             dumpkeys       login       ntfsfix        sh                              vdir
busybox             echo           loginctl    ntfsinfo       sh.distrib                      wdctl
bzcat               ed             lowntfs-3g  ntfsls         sleep                           which
bzcmp               egrep          ls          ntfsmove       ss                              whiptail
bzdiff              false          lsblk       ntfsrecover    static-sh                       wslpath
bzegrep             fgconsole      lsmod       ntfssecaudit   stty                            ypdomainname
bzexe               fgrep          mkdir       ntfstruncate   su                              zcat
bzfgrep             findmnt        mkfs.btrfs  ntfsusermap    sync                            zcmp
bzgrep              fsck.btrfs     mknod       ntfswipe       systemctl                       zdiff
bzip2               fuser          mktemp      open           systemd                         zegrep
bzip2recover        fusermount     more        openvt         systemd-ask-password            zfgrep
bzless              getfacl        mount       pidof          systemd-escape                  zforce
bzmore              grep           mountpoint  ping           systemd-hwdb                    zgrep
cat                 gunzip         mt          ping4          systemd-inhibit                 zless
chacl               gzexe          mt-gnu      ping6          systemd-machine-id-setup        zmore
chgrp               gzip           mv          plymouth       systemd-notify                  znew
chmod               hostname       nano        ps             systemd-sysusers
chown               ip             nc          pwd            systemd-tmpfiles
chvt                journalctl     nc.openbsd  rbash          systemd-tty-ask-password-agent

If you've got eagle eyes, you may have noticed that the bin directory includes bash, along with the very commands you've been running in this guide! Including pwd, ls and many more.

Bash interpretes our commands and executes the binary/executable file assosiated with the command, along with passing any arguments or options that came in with the command to the binary.

For example, when we run ls -l, Bash executes the ls executable, passing it -l as an arument.

ls is written to do one job and do it very well! Listing the contents of a directory that we pass it and return some output!

Once the ls program has finished, Bash takes the output from ls and displays it in the terminal for us to see.

If at any point you want to clear the terminal, simply run the following command:


Let's go up a level, back to the root of the system:

cd ..

You could have alternatively used cd / or cd -!

Let's finish up our quick tour by heading back to the home directory, or feel free to have a look around your system. If at any point you want to get home, just use cd ~.

Take a pick from cd, cd ~ or cd ~username to get back to your home directory.

Shell scripts

Bash is not only a shell and command interpreter, it's a scripting language that let's us write commands and scripts in a file, which we can call from bash to run.

When a shell script is executed, it's run from top to bottom and each command is executed as it's read.

In this example, we're going to create and run a very simple shell script, but don't be fooled, the Bash syntax allows us to be quite expressive, featuring looping, arrays, arguments, control flow & more.

We'll cover Bash scripting in its own section in the series.

To get started, make sure you're in your home directory:

cd ~

We're going to create a file with the nano text editor, a simple editor shiped with most distributions of linux which we can use to create, edit and save files from the terminal. We'll call our file hello.sh.

Shell scripts, just like any other file type have an assosiated file extension, which is .sh.

Go ahead and enter the following command to create the file and open it with nano:

nano hello.sh

Just like the commands we've been using in this guide, the nano command takes an optional filename to create and simultaniously open, ready for editing.

The first line of a shell script needs to include the following:


This line, often called a "Shebang", "shabang" or just "bang", tells our machine that this file should be executed by /bin/bash.

The next line is just a comment, denoted by the leading #:

# My first shell script

On a new line, go ahead and add the following:

echo "Hello $USER!"

The echo command will print things to the terminal, just like Pythons' print() function.

We're passing it the string argument of "Hello $USER!", with $USER being one of Bash's internal variables that references the current user. There are lots of Bash internal variables and we'll cover them in another guide. We'll cover the echo command in a future episode too!

Let's add some more code to our script:

echo "Your home directory is: $HOME"

$HOME is another internal variable and represents the users home directory.

echo "You are currently located in the following directory.."

You've seen the pwd command already. We can put bash commands on their own line and don't need to pass them as arguments to echo to see their output!

Let's finish up our simple script:

echo "This file is called $0"
echo "Received $# arguments"
echo "First argument: $1"
echo "Second argument: $2"
echo "Third argument: $3"
echo "Done"

We can access any incoming arguments using $1, $2, $3 etc.. With $0 being a reference to the file itself.

$# will return the number of arguments received.

Our finished script looks like this:


# My first shell script

echo "Hello $USER!"
echo "Your home directory is: $HOME"

echo "You are currently located in the following directory.."

echo "This file is called $0"
echo "Received $# arguments"

echo "First argument: $1"
echo "Second argument: $2"
echo "Third argument: $3"

echo "Done"

Save and close the file with Ctrl + x, followed by y then Enter.

Running a shell script

To run our shell script, we use the sh command, followed by the name of the file:

sh hello.sh

You should see something similar to the following:

Hello julian!
Your home directory is: /home/julian
You are currently located in the following directory..
This file is called hello.sh
Received 0 arguments
First argument:
Second argument:
Third argument:

Let's try it with some positional arguments!:

sh hello.sh one two three

We get the following:

Hello julian!
Your home directory is: /home/julian
You are currently located in the following directory..
This file is called hello.sh
Received 3 arguments
First argument: one
Second argument: two
Third argument: three

We can see the 3 arguments we passed to our script have been interpolated by $1, $2 and $3 in our script.

Wrapping up

This was designed to be a gentle introduction to Bash and should hopefully give you just enough knowledge to be able to navigate your system, list the contents of a directory, access the manual and write simple shell scripts.

In the next part of the series, we'll discuss the Linux file/directory structure in more detail and explain more about the directories you saw at the root of the system!

Last modified · 27 Mar 2019
Did you find this article useful?
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License