Join my Bash scripting course on Udemy πŸ‘€

Bash Tutorial - Starting with Bash shell basics

Updated Oct 28, 2020  ‐ 16Β min read

The command-line can seem quite daunting at first. There is no holding hands as provided by a graphical file browser for example. But when you get up to speed with it, there is no looking back.

On most Unix systems the the program that act as the command-line is the Bash shell. On the command-line you feed commands to Bash, and Bash makes sure the related program runs.

You can best view the shell as an interface to your operating system. It is a program that translates your input to instructions for the operating system.

Bash is common but not your only choice for a command-line shell. These days Zsh and Fish are popular as well. But those shells will not be covered here.

This tutorial goes into the basics of interacting with the command-line. After reading you should feel comfortable enough to use it for basic operations. Lets get started.

Content

The command prompt

The command prompt is the first notable thing you see when you open your terminal or console application. It will probably look somewhat like this:

koen@helios:~$

You can customize this to all your likings, so it is not guaranteed to look like this. But most likely it shows:

  • Your username on the system, koen in my case.
  • The name that is given to your system, this is called the hostname.
  • The current directory shown as a ~ in this example, we get into that later.

Now that we dissected that. Lets start with what the command-line is for: running commands.

koen@helios:~$ echo "How Do Fish Breathe Underwater?"

The echo command we ran here is builtin to Bash. Its basic usage is to print out text that you supplied it as argument. You see this happening when you press Enter. The argument, between quotes, was written back to you by Bash on the next line.

koen@helios:~$ echo "How Do Fish Breathe Underwater?"
How Do Fish Breathe Underwater?
koen@helios:~$

Now that we covered running commands. Lets take a look at what that ~ meant.

When you open your terminal you are likely in the "Home" directory of your user. It is practically the same as opening a graphical file browser. But with text just text instead of icons for folders and files.

To see what the actual location on the file system is that you're at you use the pwd command. Easily to remember as Print the name of my current Working Directory.

koen@helios:~$ pwd
/home/koen

What this shows is that I am in a folder called koen, which is in a folder called home, which is in de root of the file system. The root of the file system is indicated with a / at the beginning of the path.

Listing files and directories

It is nice to have a sense of where we are. It is even nicer to known what is actually there. For that use-case we have the ls command to list files and directories.

koen@helios:~$ ls
Desktop  Documents  Downloads  Music  Pictures  Public  Templates  Videos

This displayed all the contents that are in the directory /home/koen, which are in this case only folders and not files.

Command options

With the use of "options" the ls command can come in many forms. Like most commands actually. You can modify the output or behavior of commands by appending these options. By passing the option -l for example you get more detailed information about files and folders.

Options come as words or as single letters. Single letter options use a single - to indicate an option, -l in this case. If you don't use a - it is interpreted as a argument. Options that are full words use --, an example would be ls --version.

In this case the -l option of the ls command causes the file list to be more "list like" and it shows some scary things as well. Like drwxr-xr-x, these are file permissions which we will cover later.

koen@helios:~$ ls -l
total 48
drwxrwxr-x 43 koen koen  4096 sep 22 10:37 Code
drwxr-xr-x  2 koen koen  4096 aug 22 09:32 Desktop
drwxr-xr-x  8 koen koen  4096 okt 18 12:35 Documents
drwxr-xr-x  2 koen koen 12288 okt 18 12:35 Downloads
drwxr-xr-x  2 koen koen  4096 mei 20 23:58 Music
drwxr-xr-x  2 koen koen 12288 okt 14 13:31 Pictures
drwxr-xr-x 19 koen koen  4096 sep 15 14:07 snap
drwxr-xr-x  2 koen koen  4096 jun  1 19:42 Videos

Listing files in a specific folder

Now that we have a sense of where we are. We are not just bound to exploring the contents of the current folder. By passing an argument to ls we can just as well show the contents of other folders.

To see what is hiding in the Downloads folder we pass Downloads as an argument to ls. Keep in mind here that Bash is case-sensitive. So ls downloads is not the same as ls Downloads.

koen@helios:~$ ls Downloads
'Pizza: A Global History.pdf'

Right that is a must-read indeed.

You should have TAB completion for this. So as soon as you typed ls Dow you should be able to press TAB, and Bash will autocomplete. This TAB completion works if there is one unique match for your argument. So if you would type ls Do and press TAB Bash nothing happens. Since both "Downloads" and "Documents" start with "Do". If you press TAB twice though Bash will show the matching suggestions.

koen@helios:~$ ls Do
Documents/ Downloads/

Moving around

That listing the files in the Downloads folder could have been done in a two-step process as well. By moving into that folder and list the files and directories from there.

To move around we use cd to change directory.

koen@helios:~$ cd Downloads
koen@helios:~/Downloads$ ls
'Pizza: A Global History.pdf'

Notice that for the first time the command didn't output anything. In many cases in Bash, no output is good output. For commands like cd you generally only see output when an error occurs. Like when you try to move into a non-existing directory for example.

You might have noticed that the prompt changed as well. Instead of ~ now ~/Downloads is shown. As mentioned earlier the prompt shows the current working directory. That tilde(~) character is an abbreviation for your "Home" directory, so /home/koen is my case.

Absolute and relative paths

To move back to the "Home" directly you can use cd /home/koen, if your user is called "koen" at least. The /home/koen part is what is called an absolute path because starts from the root of the file system(/) till where you want to end up. This is in contrary to navigation with relative paths like the double dots we saw earlier. Where you navigate relative from your current working directory or relative from your home directory.

Going up a directory

To get back in our home directory again for the "Downloads" we have to go one directory "up". Therefor we use cd .., the .. reference the parent directory of the current directory. So cd .. would translate to: change directory to the parent directory of my current working directory.

Going from /home/koen/Downloads to /home/koen again.

koen@helios:~/Downloads$ cd ..
koen@helios:~$

Returning home

Since going to your home directory is quite common this is the default for cd if you don't provide it an argument. So instead of the cd .. from above you could actually achieve the same with just cd in this case.

More on cd

Since you're gonna use cd lots of times. Here is a little overview of useful commands. They are assumed to be ran from the home directory for this example.

CommandWhere you end upExplanation
cd/home/koenYour home directory is the default for cd, so wherever you run this you return home.
cd ~/home/koenThe ~ is a shortcut for your home directory, you can use it in commands as well.
cd ../homeYou go one directory up in the file system tree.
cd ../koen/home/koenYou go one directory up in the file system tree and from here you go in the directory koen.
cd Downloads/home/koen/DownloadsGo into the Downloads folder from your current directory.
cd ~/Downloads/home/koen/DownloadsGo into the Downloads folder from your home directory.
cd /home/koen/home/koenGo to your home directory by using an absolute path.

Files and directories

In the previous section we moved around in directories that were already there. In this section we learn to make our own directories and files using the shell and manipulate them.

Creating files and directories

To make a new directory you use mkdir.

koen@helios:~$ mkdir juice
koen@helios:~$

As mentioned before, ofter no news is good news with Bash. We don't actually get feedback that the directory is created but it is there, as we check with ls.

koen@helios:~$ ls
Code  Desktop  Documents  Downloads  juice  Music  Pictures  snap  Videos

To give an example if bad news. You can move one directory up, outside of your home directory. If you try to make a directory here you normally see an error message. We get into permissions later, but as the message says your user does not have permissions to create a directory here.

koen@helios:~$ cd ..
koen@helios:/home$ mkdir lemonjuice
mkdir: cannot create directory β€˜lemonjuice’: Permission denied

Lets get back to the safety of our home folder before we continue.

koen@helios:/home$ cd
koen@helios:~$

Directories are pretty useless when they are empty. So lets fill one we created earlier with some juice recipes. For creating files we can use the touch command.

koen@helios:~$ touch juice/apple-juice.txt
koen@helios:~$

Again no news is good news. We can speed things up a bit and create multiple files at once by passing multiple arguments.

koen@helios:~$ touch juice/tomato-juiec.txt juice/banana-smoothie.txt
koen@helios:~$

If we now list the contents of the juice folder with ls we see the files we created with touch.

koen@helios:~$ ls juice/
apple-juice.txt  banana-smoothie.txt  tomato-juiec.txt

Moving files

The command to move files and directories is mv. You use it to move files and directories around. Like how you would drag files and folders around in a graphical file browser.

To move a file or directory you pass two arguments to the mv command. First you specify what you want to move and second where you want to move it to.

Another practical use-case is renaming files so lets use the mv command to fix that typo I made before.

koen@helios:~$ mv juice/tomato-juiec.txt juice/tomato-juice.txt
koen@helios:~$ ls juice/
apple-juice.txt  banana-smoothie.txt  tomato-juice.txt

Lets say that we want to categorize a bit more. We have a smoothie in there which is sorta juice but also sorta not. To do this we'll add a subdirectory to the juice folder and move the banana-smoothie.txt file in there.

koen@helios:~$ mkdir juice/smoothie
koen@helios:~$ mv juice/banana-smoothie.txt juice/smoothie/

Where before we had to specify the file name to move it. Here the destination we passed to the mv is a directory. To check whether this worked we can use the tree command. This command lists directory structures. By default it is might not available though.

To check the files and folders in the juice folder we pass it as an argument to the tree command and see for yourself. In the juice folder there now is a smoothie folder containing the banana-smoothie.txt file.

koen@helios:~$ tree juice/
juice/
β”œβ”€β”€ apple-juice.txt
β”œβ”€β”€ smoothie
β”‚Β Β  └── banana-smoothie.txt
└── tomato-juice.txt

1 directory, 3 files

Copying files and directories

Lets say I want to make banana-kiwi smoothies too. Which are pretty similar to banana smoothies so it would be a waste of time to rewrite the whole file. This is where to cp command comes in handy.

koen@helios:~$ cd juice/smoothie/
koen@helios:~/juice/smoothie$ cp banana-smoothie.txt banana-kiwi-smoothie.txt
koen@helios:~/juice/smoothie$ ls
banana-kiwi-smoothie.txt  banana-smoothie.txt

Look at that, super easy. And it works for directories too. However, when you want to copy a directory you need to use the -r option which stands for recursively. Which basically means, copy the folder and its contents to a new location.

koen@helios:~/juice$ cp -r smoothie/ healthy
koen@helios:~/juice$ tree
.
β”œβ”€β”€ apple-juice.txt
β”œβ”€β”€ healthy
β”‚Β Β  β”œβ”€β”€ banana-kiwi-smoothie.txt
β”‚Β Β  └── banana-smoothie.txt
β”œβ”€β”€ smoothie
β”‚Β Β  β”œβ”€β”€ banana-kiwi-smoothie.txt
β”‚Β Β  └── banana-smoothie.txt
└── tomato-juice.txt

2 directories, 6 files

Removing, danger!

Okay lets face it. I am not gonna keep the juice folder and its files. So time to learn about removing files with the rm command. Some caution is necessary here. In Bash you don't have the safety net of a Thrash folder. Once it's gone it's gone.

Lets start with tomato juice since it turns out to be not very tasty. So it deserves a special treatment.

koen@helios:~/juice$ rm tomato-juice.txt
koen@helios:~/juice$ ls
apple-juice.txt  healthy  smoothie

You can't remove the directory you are currently in. Lets go back to your "Home" directory and remove the juices folder all together. Since we are now dealing with a directory we need to use the same -r option as for copying.

koen@helios:~/juice$ cd
koen@helios:~$ rm -r juice/

So the juices folder is gone now and there is no way to get it back unless we had a backup.

Hidden files

A special kind of files and directories are hidden ones. Since they are hidden you might not have noticed them. Hidden files start with a .. Mostly these files are created or used by program to store data or configurations.

Bash creates these files as well, for example the .bash_history file in which your latest commands are stored. You can make these hidden files appear by adding the -a option to the ls command.

koen@helios:~$ ls -al
total 1040
drwxr-xr-x 35 koen koen   4096 okt 18 13:58 .
drwxr-xr-x  3 root root   4096 mei 31 12:44 ..
-rw-------  1 koen koen     11 jun 12 16:42 .bash_history
-rw-------  1 koen koen     11 jun 12 16:42 .bashrc
drwxr-xr-x 30 koen koen   4096 okt 18 09:44 .cache
drwxrwxr-x 43 koen koen   4096 sep 22 10:37 Code
drwxr-xr-x 45 koen koen   4096 sep 29 14:15 .config
...
drwxr-xr-x  2 koen koen   4096 jun  1 19:42 Videos

Permissions

Linux and pretty much all other operating systems are set up to support multiple users. So for security reasons it makes sense that not all users can access all files.

Users and groups

As we saw before, in the output of the ls -l command my name was in there twice. The first appearance on koen indicates that the file is owned by a user called koen. The second appearance is the name of a user group, in my case the group has the same name as my user.

koen@helios:~$ ls -l
total 52
drwxrwxr-x 43 koen koen  4096 sep 22 10:37 Code
...

File permissions

Why those user groups are useful have to do with file permissions. The permissions as shown using the somewhat cryptic drwxrwxr-x.

The first character in drwxrwxr-x indicates whether we are looking at a file or directory. In this case the first character is a d, for directory. For files a hyphen(-) is used.

The other characters are actually a repetition of three times three characters that specify the permissions. The characters are r, w and x and they mean the following:

  • Read (r) permissions for the file or directory. This means you can view the file contents if it is a file or list the contents of the directory if it is a directory.
  • Write (w) permissions to the file or directory. Meaning you can change the content of the file. Or in case of a directory, you can modify its content like deleting files.
  • Execute (x) permissions. Meaning you can execute the file, like using it as a command. Or cd into it if it's a directory.

This sequence of three characters is repeated three times to indicate the permissions for the owner, user group and the others. Seeing the character means the permission is applicable, if you see a hyphen it means you don't have that permission.

So to use drwxrwxr-x as an example. We covered d already. Next is rwx for the file owner. This means that the file owner has read, write and executable permissions for this directory. Next is again rwx, meaning that all users belonging to the group have read, write and executable permissions as well. At last is r-x, these are permissions for all users that are not the file owner and do not belong to the user group. In this case all other users have permissions to read and execute. Not to write because at the position of the w a hyphen is shown.

Root user

There is one special user which is called root. This user is a superuser account which have more access rights. You use this user mostly to do administrative tasks, like installing a new package for example.

Most commonly to do so is by using a program called sudo. Which allow you to do something as super user. You put this in front of the command you would like to execute. Like this for example, you are most likely prompted for you password when you run it.

koen@helios:~$ sudo mkdir /home/test