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.
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:
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,
koenin 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?"
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
Navigate through the file system
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.
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
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
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/
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
~/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.
koen@helios:~/Downloads$ cd .. koen@helios:~$
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.
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.
|Command||Where you end up||Explanation|
|Your home directory is the default for |
|You go one directory up in the file system tree.|
|You go one directory up in the file system tree and from here you go in the directory |
|Go into the |
|Go into the |
|Go 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
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
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
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
koen@helios:~$ ls juice/ apple-juice.txt banana-smoothie.txt tomato-juiec.txt
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
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
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.
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
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
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 ...
Why those user groups are useful have to do with file permissions. The permissions as shown using the somewhat cryptic
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
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
cdinto 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.
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