Bash Scripting Tutorial
Bash Scripting Tutorial
Menu
Shell
Shell is a macro processor which allows for an interactive or non-interactive
command execution.
Scripting
Scripting allows for an automatic commands execution that would otherwise
be executed interactively one-by-one.
https://linuxconfig.org/bash-scripting-tutorial-for-beginners 1/52
11/26/21, 10:49 PM Bash Scripting Tutorial for Beginners - Linux Tutorials - Learn Linux Configuration
In case you did not know, Bash Scripting is a must skill for any Linux system
administration job even though it may not be implicitly requested by the employer.
What is Shell
Most likely, you are at the moment sitting in front of your computer, have a terminal
window opened and wondering: “What should I do with this thing?”
Well, the terminal window in front of you contains shell, and shell allows you by use
of commands to interact with your computer, hence retrieve or store data, process
information and various other simple or even extremely complex tasks.
Try it now! Use your keyboard and type some commands such as date , cal , pwd
or ls followed by the ENTER key.
linuxconfig.org:~$ date
Fri 31 Mar 11:44:46 AEDT 2017
linuxconfig.org:~$ cal
March 2017
Su Mo Tu We Th Fr Sa
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
linuxconfig.org:~$ pwd
/home/linuxconfig
linuxconfig.org:~$ ls
hello-world.sh
linuxconfig.org:~$
00:00
What you have just done, was that by use of commands and shell you interacted with
your computer to retrieve a current date and time ( date ), looked up a calendar
https://linuxconfig.org/bash-scripting-tutorial-for-beginners 2/52
11/26/21, 10:49 PM Bash Scripting Tutorial for Beginners - Linux Tutorials - Learn Linux Configuration
( cal ), checked the location of your current working directory ( pwd ) and retrieved a
list of all files and directories located within ( ls ).
What is Scripting
Now, imagine that the execution of all the above commands is your daily task. Every
day you are required to execute all of the above commands without fail as well as
store the observed information. Soon enough this will become an extremely tedious
task destined for failure. Thus the obvious notion is to think of some way to execute
all given commands together. This is where scripting becomes your salvation.
To see what is meant by scripting, use shell in combination with your favorite text
editor eg. vi to create a new file called task.sh containing all the above commands,
each on a separate line. Once ready, make your new file executable using chmod
command with an option +x . Lastly, execute your new script by prefixing its name
with ./ .
linuxconfig.org:~$ vi task.sh
linuxconfig.org:~$ chmod +x task.sh
linuxconfig.org:~$ ./task.sh
Fri 31 Mar 12:56:09 AEDT 2017
March 2017
Su Mo Tu We Th Fr Sa
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
/home/linuxconfig
hello-world.sh task.sh
linuxconfig.org:~$
00:00
As you can see, by use of scripting, any shell interaction can be automated and
scripted. Furthermore, it is now possible to automatically execute our new shell
script task.sh daily at any given time by use of cron time-based job scheduler and
store the script’s output to a file every time it is executed. However, this is a tale for
an another day, for now let’s just concentrate on a task ahead.
What is Bash
https://linuxconfig.org/bash-scripting-tutorial-for-beginners 3/52
11/26/21, 10:49 PM Bash Scripting Tutorial for Beginners - Linux Tutorials - Learn Linux Configuration
So far we have covered shell and scripting. What about Bash? Where does the bash
fit in? As already mentioned, the bash is a default interpreter on many GNU/Linux
systems, thus we have been using it even without realising. This is why our previous
shell script works even without us defining bash as an interpreter. To see what is
your default interpreter execute command echo $SHELL :
$ echo $SHELL
/bin/bash
There are various other shell interpreters available, such as Korn shell, C shell and
more. From this reason, it is a good practice to define the shell interpreter to be
used explicitly to interpret the script’s content.
To define your script’s interpreter as Bash, first locate a full path to its executable
binary using which command, prefix it with a shebang #! and insert it as the first
line of your script. There are various other techniques how to define shell
interpreter, but this is a solid start.
/bin/bash
linuxconfig.org:~$ vi task.sh
linuxconfig.org:~$ ./task.sh
Fri 31 Mar 14:24:24 AEDT 2017
March 2017
Su Mo Tu We Th Fr Sa
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
/home/linuxconfig
hello-world.sh task.sh
linuxconfig.org:~$
00:00
From now, all our scripts will include shell interpreter definition #!/bin/bash .
https://linuxconfig.org/bash-scripting-tutorial-for-beginners 4/52
11/26/21, 10:49 PM Bash Scripting Tutorial for Beginners - Linux Tutorials - Learn Linux Configuration
In fact, the file extension on GNU/Linux systems mostly does not have any meaning
apart from the fact, that upon the execution of ls command to list all files and
directories it is immediately clear that file with extension .sh is plausibly a shell
script and file with .jpg is likely to be a lossy compressed image.
On GNU/Linux systems a file command can be used to identify a type of the file.
As you can see on the below example, the file extension does not hold any value, and
the shell interpreter, in this case, carries more weight.
00:00
Thus, shell script name 0_xyz is perfectly valid, but if possible it should be avoided.
https://linuxconfig.org/bash-scripting-tutorial-for-beginners 5/52
11/26/21, 10:49 PM Bash Scripting Tutorial for Beginners - Linux Tutorials - Learn Linux Configuration
Script Execution
Next, let’s talk about an alternative way on how to run bash scripts. In a highly
simplistic view, a bash script is nothing else just a text file containing instructions to
be executed in order from top to bottom. How the instructions are interpreted
depends on defined shebang or the way the script is executed. Consider the
following video example:
00:00
Another way to execute bash scripts is to call bash interpreter explicitly eg.
$ bash date.sh , hence executing the script without the need to make the shell
script executable and without declaring shebang directly within a shell script. By
calling bash executable binary explicitly, the content of our file date.sh is loaded
and interpreted as Bash Shell Script.
Probably the best analogy to explain a relative vs. absolute file path is to visualise
GNU/Linux filesystem as a multiple storey building. The root directory (building’s
entrance door) indicated by / provides the entry to the entire filesystem (building),
hence giving access to all directories (levels/rooms) and files (people).
To navigate to a room 1 on level 3 we first need to enter the main door / , then make
our way to level 3 level3/ and from there enter the room1 . Hence, the absolute
https://linuxconfig.org/bash-scripting-tutorial-for-beginners 6/52
11/26/21, 10:49 PM Bash Scripting Tutorial for Beginners - Linux Tutorials - Learn Linux Configuration
linuxconfig.org:~$ cd /
linuxconfig.org:/$ pwd
/
linuxconfig.org:/$ cd home/
linuxconfig.org:/home$ pwd
/home
linuxconfig.org:/home$ cd ..
linuxconfig.org:/$ pwd
/
linuxconfig.org:/$ ls
bin etc initrd.img.old lib64 media proc sbin tmp vmlinuz
boot home lib libx32 mnt root srv usr vmlinuz.old
dev initrd.img lib32 lost+found opt run sys var
linuxconfig.org:/$ cd /etc/
linuxconfig.org:/etc$ cd ../home/linuxconfig/
linuxconfig.org:~$ pwd
/home/linuxconfig
linuxconfig.org:~$ cd -
/etc
linuxconfig.org:/etc$ pwd
/etc
linuxconfig.org:/etc$ cd -
/home/linuxconfig
linuxconfig.org:~$ pwd
/home/linuxconfig
linuxconfig.org:~$ cd ../../
linuxconfig.org:/$ pwd
/
linuxconfig.org:/$ cd
linuxconfig.org:~$ pwd
/home/linuxconfig
linuxconfig.org:~$
00:00
https://linuxconfig.org/bash-scripting-tutorial-for-beginners 7/52
11/26/21, 10:49 PM Bash Scripting Tutorial for Beginners - Linux Tutorials - Learn Linux Configuration
Quick Tip:
1 #!/bin/bash
https://linuxconfig.org/bash-scripting-tutorial-for-beginners 8/52
11/26/21, 10:49 PM Bash Scripting Tutorial for Beginners - Linux Tutorials - Learn Linux Configuration
Once ready, make your script executable with the chmod command and execute it
using relative path ./hello-world.sh :
$ chmod +x hello-world.sh
$ linuxconfig.org:~$ ./hello-world.sh
Hello World
The following video example offers an alternative way of creating the above
hello-world.sh script. It uses which command to print a full path to the bash
interpreter. This output is simultaneously redirected using > redirection sign while
creating a new file hello-world.sh at the same time.
00:00
Any command which can be successfully executed directly via bash shell terminal
can be in the same form used as part of bash shell script. In fact, there is no
difference between command execution directly via terminal or within a shell script
apart from the fact that the shell script offers non-interactive execution of multiple
commands as a single process.
Quick Tip:
https://linuxconfig.org/bash-scripting-tutorial-for-beginners 9/52
11/26/21, 10:49 PM Bash Scripting Tutorial for Beginners - Linux Tutorials - Learn Linux Configuration
Regardless of the script complexity, do not attempt to write your entire script in
one go. Slowly develop your script by testing each core line by executing it first on
the terminal command line. When successful, transfer it to your shell script.
Each command comes with a manual page which can be used to learn about its
function as well as what options and arguments each specific command accepts.
Use man command to display manual page of any desired command. For example to
display a manual page for the ls command execute man ls . To quit from manual
page press q key.
The below ls command example shows a basic use of command line options and
arguments.
linuxconfig.org:~$ ls
0_xvz date.sh hello-world.sh task.sh
linuxconfig.org:~$ ls -l
total 16
-rwxr-xr-x 1 linuxconfig linuxconfig 19 Mar 31 15:23 0_xvz
-rwxr-xr-x 1 linuxconfig linuxconfig 18 Jul 20 11:46 date.sh
-rwxr-xr-x 1 linuxconfig linuxconfig 32 Mar 31 11:49 hello-world.sh
-rwxr-xr-x 1 linuxconfig linuxconfig 29 Mar 31 14:24 task.sh
linuxconfig.org:~$ ls -l
00:00
Although our first “Hello World” shell script requires a solid understanding of the
file creation, editing and script execution, its usability can be clearly questioned.
The next example offers more practical application as it can be used to backup our
user home directory. To create the backup script, on Line 3 we will be using tar
command with various options -czf in order to create a compressed tar ball of
https://linuxconfig.org/bash-scripting-tutorial-for-beginners 10/52
11/26/21, 10:49 PM Bash Scripting Tutorial for Beginners - Linux Tutorials - Learn Linux Configuration
entire user home directory /home/linuxconfig/ . Insert the following code into a
new file called backup.sh , make the script executable and run it:
1 #!/bin/bash
00:00
Quick Tip:
Enter man tar command to learn more about all tar command
line options used within the previous backup.sh script. Try to run the tar
command without - option prefix! Does it work?
https://linuxconfig.org/bash-scripting-tutorial-for-beginners 11/52
11/26/21, 10:49 PM Bash Scripting Tutorial for Beginners - Linux Tutorials - Learn Linux Configuration
Variables
Variables are the essence of programming. Variables allow a programmer to store
data, alter and reuse them throughout the script. Create a new script welcome.sh
with the following content:
1 #!/bin/bash
3 greeting="Welcome"
4 user=$(whoami)
5 day=$(date +%A)
By now you should possess all required skills needed to create a new script, making
it executable and running it on the command line. After running the above
welcome.sh script, you will see an output similar to the one below:
$ ./welcome.sh
Let’s look at the script more closely. First, we have declared a variable greeting and
assigned a string value Welcome to it. The next variable user contains a value of
user name running a shell session. This is done through a technique called
command substitution. Meaning that the output of the whoami command will be
directly assigned to the user variable. The same goes for our next variable day
which holds a name of today’s day produced by date +%A command.
https://linuxconfig.org/bash-scripting-tutorial-for-beginners 12/52
11/26/21, 10:49 PM Bash Scripting Tutorial for Beginners - Linux Tutorials - Learn Linux Configuration
The second part of the script utilises the echo command to print a message while
substituting variable names now prefixed by $ sign with their relevant values. In
case you wonder about the last variable used $BASH_VERSION know that this is a so
called internal variable defined as part of your shell.
Quick Tip:
Variables can also be used directly on the terminal’s command line. The following
example declares variables a and b with integer data. Using echo command, we
can print their values or even perform an arithmetic operation as illustrated by the
following example:
linuxconfig.org:~$ a=4
linuxconfig.org:~$ b=8
linuxconfig.org:~$ echo $a
4
linuxconfig.org:~$ echo $b
8
linuxconfig.org:~$ echo $[$a + $b]
12
linuxconfig.org:~$
00:00
Now that we have bash variable introduction behind us we can update our backup
script to produce more meaningful output file name by incorporating a date and
time when the backup on our home directory was actually performed.
Furthermore, the script will no longer be bind to a specific user. From now on our
backup.sh bash script can be run by any user while still backing up a correct user
home directory:
https://linuxconfig.org/bash-scripting-tutorial-for-beginners 13/52
11/26/21, 10:49 PM Bash Scripting Tutorial for Beginners - Linux Tutorials - Learn Linux Configuration
1 #!/bin/bash
5 user=$(whoami)
6 input=/home/$user
7 output=/tmp/${user}_home_$(date +%Y-%m-%d_%H%M%S).tar.gz
You may have already noticed that the above script introduces two new bash
scripting concepts. Firstly, our new backup.sh script contains comment line. Every
line starting with # sign except shebang will not be interpreted by bash and will
only serve as a programmer’s internal note.
Secondly, the script uses a new shell scripting trick ${parameter} called parameter
expansion. In our case, curly braces {} are required because our variable $user is
followed by characters which are not part of its variable name. Below is the output
of our newly revised backup script:
$ ./backup.sh
https://linuxconfig.org/bash-scripting-tutorial-for-beginners 14/52
11/26/21, 10:49 PM Bash Scripting Tutorial for Beginners - Linux Tutorials - Learn Linux Configuration
Every time, you execute a command, three possible outcomes might happen. The
first scenario is that the command will produce an expected output, second, the
command will generate an error, and lastly, your command might not produce any
output at all:
linuxconfig.org:~$ ls -l foobar
ls: cannot access 'foobar': No such file or directory
linuxconfig.org:~$ touch foobar
linuxconfig.org:~$ ls -l foobar
-rw-r--r-- 1 linuxconfig linuxconfig 0 Jul 28 10:08 foobar
linuxconfig.org:~$
00:00
What are we most interested in here is the output of both ls -l foobar commands.
Both commands produced an output which by default is displayed on your terminal.
However, both outputs are fundamentally different.
The first command tries to list non-existing file foobar which, in turn, produces a
standard error output (stderr). Once the file is created by touch command, the
second execution of the ls command produces standard output (stdout).
The difference between stdout and stderr output is an essential concept as it allows
us to a threat, that is, to redirect each output separately. The > notation is used to
redirect stdout to a file whereas 2> notation is used to redirect stderr and &> is
used to redirect both stdout and stderr. The cat command is used to display a
content of any given file. Consider a following example:
https://linuxconfig.org/bash-scripting-tutorial-for-beginners 15/52
11/26/21, 10:49 PM Bash Scripting Tutorial for Beginners - Linux Tutorials - Learn Linux Configuration
00:00
Replay the above video few times and make sure that you understand the redirection
concept shown.
Quick Tip:
Back to our backup.sh script. When executing our backup script, you may have
noticed an extra message display by tar command:
https://linuxconfig.org/bash-scripting-tutorial-for-beginners 16/52
11/26/21, 10:49 PM Bash Scripting Tutorial for Beginners - Linux Tutorials - Learn Linux Configuration
Now that we have a basic understanding of the output redirection we can eliminate
this unwanted stderr message by redirecting it with 2> notation to /dev/null .
Imagine /dev/null as a data sink, which discards any data redirected to it. For
more information run man null . Below is our new backup.sh version including
tar’s stderr redirection:
1 #!/bin/bash
5 user=$(whoami)
6 input=/home/$user
7 output=/tmp/${user}_home_$(date +%Y-%m-%d_%H%M%S).tar.gz
After executing a new version of our backup.sh script, no tar stderr message will
be displayed.
The last concept to briefly cover in this section is a shell input. Apart of the above
stdout and stderr descriptors bash shell also features input descriptor name stdin.
Generally, terminal input comes from a keyboard. Any keystroke you type is
accepted as stdin.
The alternative method is to accept command input from a file using < notation.
Consider the following example where we first feed cat command from the
keyboard and redirecting the output to file1.txt . Later, we allow cat command to
read the input from file1.txt using < notation:
https://linuxconfig.org/bash-scripting-tutorial-for-beginners 17/52
11/26/21, 10:49 PM Bash Scripting Tutorial for Beginners - Linux Tutorials - Learn Linux Configuration
00:00
Functions
The topic we are going to discuss next is functions. Functions allow a programmer
to organize and reuse code, hence increasing the efficiency, execution speed as well
as readability of the entire script.
It is possible to avoid using functions and write any script without including a single
function in it. However, you are likely to end up with a chunky, inefficient and hard
to troubleshoot code.
Quick Tip:
https://linuxconfig.org/bash-scripting-tutorial-for-beginners 18/52
11/26/21, 10:49 PM Bash Scripting Tutorial for Beginners - Linux Tutorials - Learn Linux Configuration
The moment you notice that your script contains two lines of the same code, you
may consider to enact a function instead.
You can think of the function as a way to the group number of different commands
into a single command. This can be extremely useful if the output or calculation you
require consists of multiple commands, and it will be expected multiple times
throughout the script execution. Functions are defined by using the function
keyword and followed by function body enclosed by curly brackets.
The following video example defines a simple shell function to be used to print user
details and will make two function calls, thus printing user details twice upon a
script execution.
The function name is user_details , and function body enclosed inside curly
brackets consists of the group of two echo commands. Every time a function call is
made by using the function name, both echo commands within our function
definition are executed. It is important to point out that the function definition must
precede function call, otherwise the script will return function not found error:
linuxconfig.org:~$ vi function.sh
linuxconfig.org:~$ chmod +x function.sh
linuxconfig.org:~$ ./function.sh
User Name: linuxconfig
Home Directory: /home/linuxconfig
linuxconfig.org:~$ vi function.sh
linuxconfig.org:~$ ./function.sh
User Name: linuxconfig
Home Directory: /home/linuxconfig
User Name: linuxconfig
Home Directory: /home/linuxconfig
linuxconfig.org:~$
00:52
The preceding video example also introduced yet another technique when writing
scripts or any program for that matter, the technique called indentation. The echo
commands within the user_details function definition were deliberately shifted
one TAB right which makes our code more readable, easier to troubleshot.
https://linuxconfig.org/bash-scripting-tutorial-for-beginners 19/52
11/26/21, 10:49 PM Bash Scripting Tutorial for Beginners - Linux Tutorials - Learn Linux Configuration
With indentation, it is much clearer to see that both echo commands below to
user_details function definition. There is no general convention on how to indent
bash script thus it is up to each individual to choose its own way to indent. Our
example used TAB. However, it is perfectly fine to instead a single TAB use 4 spaces,
etc.
Having a basic understanding of bash scripting functions up our sleeve, let's add a
new feature to our existing backup.sh script. We are going to program two new
functions to report a number of directories and files to be included as part of the
output compressed the backup file.
1 #!/bin/bash
5 user=$(whoami)
6 input=/home/$user
7 output=/tmp/${user}_home_$(date +%Y-%m-%d_%H%M%S).tar.gz
11 find $1 -type f | wc -l
12 }
13
16 function total_directories {
17 find $1 -type d | wc -l
18 }
19
21
23 total_files $input
25 total_directories $input
26
https://linuxconfig.org/bash-scripting-tutorial-for-beginners 20/52
11/26/21, 10:49 PM Bash Scripting Tutorial for Beginners - Linux Tutorials - Learn Linux Configuration
28
30 ls -l $output
After reviewing the above backup.sh script, you will notice the following changes to
the code:
Quick Tip:
Read manual pages, if you wish to learn more about find , wc and
echo command's options used by our backup.sh bash script. Example:
$ man find
Once you update your script to include new functions, the execution of the script
will provide a similar output to the one below:
$ ./backup.sh
Files to be included:19
Directories to be included:2
https://linuxconfig.org/bash-scripting-tutorial-for-beginners 21/52
11/26/21, 10:49 PM Bash Scripting Tutorial for Beginners - Linux Tutorials - Learn Linux Configuration
equal -eq =
After reviewing the above table, let's say, we would like to compare numeric values
like two integers 1 and 2 . The following video example will first define two
variables $a and $b to hold our integer values.
Next, we use square brackets and numeric comparison operators to perform the
actual evaluation. Using echo $? command, we check for a return value of the
https://linuxconfig.org/bash-scripting-tutorial-for-beginners 22/52
11/26/21, 10:49 PM Bash Scripting Tutorial for Beginners - Linux Tutorials - Learn Linux Configuration
linuxconfig.org:~$ a=1
linuxconfig.org:~$ b=2
linuxconfig.org:~$ [ $a -lt $b ]
linuxconfig.org:~$ echo $?
0
linuxconfig.org:~$ [ $a -gt $b ]
linuxconfig.org:~$ echo $?
1
linuxconfig.org:~$ [ $a -eq $b ]
linuxconfig.org:~$ echo $?
1
linuxconfig.org:~$ [ $a -ne $b ]
linuxconfig.org:~$ echo $?
0
linuxconfig.org:~$
00:00
Using string comparison operators we can also compare strings in the same manner
as when comparing numeric values. Consider the following example:
00:00
If we were to translate the above knowledge to a simple bash shell script, the script
would look as shown below. Using string comparison operator = we compare two
distinct strings to see whether they are equal.
https://linuxconfig.org/bash-scripting-tutorial-for-beginners 23/52
11/26/21, 10:49 PM Bash Scripting Tutorial for Beginners - Linux Tutorials - Learn Linux Configuration
1 #!/bin/bash
3 string_a="UNIX"
4 string_b="GNU"
7 [ $string_a = $string_b ]
8 echo $?
10 num_a=100
11 num_b=100
12
15 echo $?
Save the above script as eg. comparison.sh file, make it executable and execute:
$ chmod +x compare.sh
$ ./compare.sh
Quick Tip:
Apart from the educational value, the above script does not serve any other purpose.
Comparisons operations will make more sense once we learn about conditional
https://linuxconfig.org/bash-scripting-tutorial-for-beginners 24/52
11/26/21, 10:49 PM Bash Scripting Tutorial for Beginners - Linux Tutorials - Learn Linux Configuration
statements like if/else. Conditional statements will be covered in the next chapter,
and this is where we put comparison operations to better use.
Conditional Statements
Now, it is time to give our backup script some logic by including few conditional
statements. Conditionals allow the programmer to implement decision making
within a shell script based on certain conditions or events.
The conditionals we are referring to are of course, if , then and else . For
example, we can improve our backup script by implementing a sanity check to
compare the number of files and directories within a source directory we intend to
backup and the resulting backup file. The pseudocode for this kind of
implementation will read as follows:
IF the number of files between the source and destination target is equal THEN
print the OK message, ELSE , print ERROR.
https://linuxconfig.org/bash-scripting-tutorial-for-beginners 25/52
11/26/21, 10:49 PM Bash Scripting Tutorial for Beginners - Linux Tutorials - Learn Linux Configuration
1 #!/bin/bash
3 num_a=100
4 num_b=200
8 fi
For now the else conditional was deliberately left out, we will include it once we
understand the logic behind the above script. Save the script as, eg. if_else.sh and
execute it:
00:00
The important observation to make from the script execution is that, in the situation
when the variable $num_a greater than $num_b our script fails to react. This is
where the last piece of the puzzle, else conditional comes in handy. Update your
script by adding else block and execute it:
1 #!/bin/bash
3 num_a=400
4 num_b=200
https://linuxconfig.org/bash-scripting-tutorial-for-beginners 26/52
11/26/21, 10:49 PM Bash Scripting Tutorial for Beginners - Linux Tutorials - Learn Linux Configuration
8 else
10 fi
The Line 8 now holds the else part of our conditional block. If the comparison
evaluation on Line 6 reports false the code below else statement, in our case
Line 9 is executed.
linuxconfig.org:~$ ./if_else.sh
100 is less than 200!
linuxconfig.org:~$ vi if_else.sh
linuxconfig.org:~$ ./if_else.sh
800 is greater than 200!
linuxconfig.org:~$
00:00
Exercise:
Can you rewrite the if_else.sh script to reverse the logic of its
execution in a way that the else block gets executed if the variable $num_a is less
than variable $num_b ?
Equipped with this basic knowledge about the conditional statements we can now
improve our script to perform a sanity check by comparing the difference between
the total number of the files before and after the backup command. Here is the new
updated backup.sh script:
1 #!/bin/bash
3 user=$(whoami)
4 input=/home/$user
5 output=/tmp/${user}_home_$(date +%Y-%m-%d_%H%M%S).tar.gz
7 function total_files {
https://linuxconfig.org/bash-scripting-tutorial-for-beginners 27/52
11/26/21, 10:49 PM Bash Scripting Tutorial for Beginners - Linux Tutorials - Learn Linux Configuration
8 find $1 -type f | wc -l
9 }
10
11 function total_directories {
12 find $1 -type d | wc -l
13 }
14
15 function total_archived_directories {
17 }
18
19 function total_archived_files {
21 }
22
24
27
30
35
39 ls -l $output
40 else
42 fi
There are few additions to the above script. Highlighted are the most important
changes.
https://linuxconfig.org/bash-scripting-tutorial-for-beginners 28/52
11/26/21, 10:49 PM Bash Scripting Tutorial for Beginners - Linux Tutorials - Learn Linux Configuration
Lines 15 - 21 are used to define two new functions returning a total number of files
and directories included within the resulting compressed backup file. After the
backup Line 23 is executed, on Lines 25 - 29 we declare new variables to hold the
total number of source and destination files and directories.
The variables concerning backed up files are later used on Lines 36 - 42 as part of
our new conditional if/then/else statement returning a message about the successful
backup on Lines 37 - 39 only if the total number of both, source and destination
backup files is equal as stated on Line 36 .
$ ./backup.sh
Files to be included: 24
Directories to be included: 4
Files archived: 24
Directories archived: 4
Positional Parameters
https://linuxconfig.org/bash-scripting-tutorial-for-beginners 29/52
11/26/21, 10:49 PM Bash Scripting Tutorial for Beginners - Linux Tutorials - Learn Linux Configuration
So far our backup script looks great. We can count the number of files and
directories included within the resulting compressed backup file. Furthermore, our
script also facilitates a sanity check to confirm that all files have been correctly
backed up. The disadvantage is that we are always forced to backup a directory of a
current user. It would be great if the script would be flexible enough to allow the
system administrator to backup a home directory of any selected system user by
merely pointing the script to its home directory.
When using bash positional parameters, this is rather an easy task. Positional
parameters are assigned via command line arguments and are accessible within a
script as $1, $2...$N variables. During the script execution, any additional items
supplied after the program name are considered arguments and are available during
the script execution. Consider the following example:
00:00
1 #!/bin/bash
3 echo $1 $2 $4
4 echo $#
5 echo $*
On the Line 3 we print 1st, 2nd and 4th positional parameters exactly in order as
they are supplied during the script's execution. The 3rd parameter is available, but
deliberately omitted on this line. Using $# on Line 4 , we are printing the total
number of supplied arguments. This is useful when we need to check how many
https://linuxconfig.org/bash-scripting-tutorial-for-beginners 30/52
11/26/21, 10:49 PM Bash Scripting Tutorial for Beginners - Linux Tutorials - Learn Linux Configuration
arguments the user provided during the script execution. Lastly, the $* on Line 5 ,
is used to print all arguments.
Armed with the positional parameters knowledge let's now improve our backup.sh
script to accept arguments from a command line. What we are looking for here is to
let the user decide what directory will be backed up. In case that no argument is
submitted by the user during the script's execution, by default the script will backup
a current user's home directory. The new script is below:
1 #!/bin/bash
2
3 # This bash script is used to backup a user's home directory
4
5 if [ -z $1 ]; then
6 user=$(whoami)
7 else
8 if [ ! -d "/home/$1" ]; then
9 echo "Requested $1 user home directory doesn'
10 exit 1
11 fi
12 user=$1
13 fi
14
15 input=/home/$user
16 output=/tmp/${user}_home_$(date +%Y-%m-%d_%H%M%S).tar.gz
17
18 function total_files {
19 find $1 -type f | wc -l
20 }
21
22 function total_directories {
23 find $1 -type d | wc -l
24 }
25
26 function total_archived_directories {
27 tar -tzf $1 | grep /$ | wc -l
28 }
https://linuxconfig.org/bash-scripting-tutorial-for-beginners 31/52
11/26/21, 10:49 PM Bash Scripting Tutorial for Beginners - Linux Tutorials - Learn Linux Configuration
29
30 function total_archived_files {
31 tar -tzf $1 | grep -v /$ | wc -l
32 }
33
34 tar -czf $output $input 2> /dev/null
35
36 src_files=$( total_files $input )
38
41
46
50 ls -l $output
51 else
53 fi
The above backup.sh script update introduces few new bash scripting techniques
but rest for the code between Lines 5 - 13 should be by now self-explanatory.
Line 5 is using a -z bash option in combination with conditional if statement to
check whether positional parameter $1 contains any value. -z simply returns true
if the length of the string which in our case is variable $1 is zero. If this is the case,
we set $user variable to a current user's name.
Else on Line 8 , we check if the requested user's home directory exists by using -d
bash option. Note the exclamation mark before the -d option. Exclamation mark, in
this case, acts as a negator. By default -d option returns true if the directory exists,
hence our ! just reverts the logic and on Line 9 we print an error message.
https://linuxconfig.org/bash-scripting-tutorial-for-beginners 32/52
11/26/21, 10:49 PM Bash Scripting Tutorial for Beginners - Linux Tutorials - Learn Linux Configuration
Line 10 uses exit command causing script execution termination. We have also
assigned exit value 1 as opposed to 0 meaning that the script exited with an error.
If the directory check passes validation, on Line 12 we assign our $user variable to
positional parameter $1 as requested during by the user.
$ ./backup.sh
Files to be included: 24
Directories to be included: 4
Files archived: 24
Directories archived: 4
$ ./backup.sh abc123
$ ./backup.sh damian
Files to be included: 3
Directories to be included: 1
Files archived: 3
Directories archived: 1
Quick Tip:
Check bash manual page with $ man bash command for more
information about -z , -d and other bash options. Currently, the default storage
directory is /tmp . Perhaps the script could be more flexible? Can you think of a
way to use positional parameter $2 to let the user to decide on which directory to
use to store the resulting backup file?
https://linuxconfig.org/bash-scripting-tutorial-for-beginners 33/52
11/26/21, 10:49 PM Bash Scripting Tutorial for Beginners - Linux Tutorials - Learn Linux Configuration
Bash Loops
So far our backup script functions as expected and its usability has been
substantially increased in comparison with the initial code introduced at the
beginning of this scripting tutorial. We can now easily backup any user directory by
pointing the script to user's home directory using positional parameters during the
script's execution.
The trouble only arises when we need to backup multiple user directories on a daily
basis. Hence this task will very quickly become tedious and time-consuming. At this
stage, it would be great to have the means to backup any number of selected user
home directories with a single backup.sh script execution.
Fortunately, bash has us covered, as this task can be accomplished by use of loops.
Loops are looping constructs used to iterate through any given number of tasks until
all items in a specified list were completed or predefined conditions were met.
There are three basic loop types available to our disposal.
For Loop
For loop is used to iterate through any given code for any number of supplied items
in the list. Let's start with a simple for loop example:
https://linuxconfig.org/bash-scripting-tutorial-for-beginners 34/52
11/26/21, 10:49 PM Bash Scripting Tutorial for Beginners - Linux Tutorials - Learn Linux Configuration
00:00
The above for loop has used the echo command to print all items 1 , 2 and 3 in
the list. Using a semicolon allows us to execute for loop on a single command line. If
we were to transfer the above for loop into a bash script, the code would look like
follows:
1 #!/bin/bash
3 for i in 1 2 3; do
4 echo $i
5 done
The for loop consists of four Shell Reserved Words: for, in, do, done. The above code
can therefore also be read as: FOR each item IN list 1 , 2 and 3 assign each item
temporarily into a variable i after which DO echo $i in order to print the item as
STDOUT and keep printing until all items IN the list are DONE .
Printing numbers is undoubtedly fun but let's try something more meaningful
instead. Using command substitution as explained earlier in this tutorial we can
create any kind of list to be a part of for loop construct. The following slightly more
sophisticated for loop example will count characters of each line for any given file:
linuxconfig.org:~$ vi items.txt
linuxconfig.org:~$ cat items.txt
bash
scripting
tutorial
linuxconfig.org:~$ for i in $( cat items.txt ); do echo -n $i | wc -c; done
4
9
8
linuxconfig.org:~$
00:00
Yes, when mastered, the power of GNU Bash knows no limits! Take your time to
https://linuxconfig.org/bash-scripting-tutorial-for-beginners 35/52
11/26/21, 10:49 PM Bash Scripting Tutorial for Beginners - Linux Tutorials - Learn Linux Configuration
Exercise:
Rewrite the above character count for loop to print names of all
files and directories inside your current working directory along with the number
of characters each file and directory name consists from. The for loop output
should look similar to:
0_xvz has 5
backup.sh has 9
compare.sh has 10
date.sh has 7
file1.txt has 9
foobar has 6
function.sh has 11
hello-world.sh has 14
if_else.sh has 10
items.txt has 9
While Loop
The next loop construct on our list is while loop. This particular loop acts on a given
condition. Meaning, it will keep executing code enclosed withing DO and DONE
while the specified condition is true. Once the specified condition becomes false, the
execution will stop. Consider the following example:
1 #!/bin/bash
3 counter=0
5 let counter+=1
6 echo $counter
7 done
This particular while loop will keep executing the enclosed code only while the
counter variable is less than 3. This condition is set on Line 4 . During each loop
https://linuxconfig.org/bash-scripting-tutorial-for-beginners 36/52
11/26/21, 10:49 PM Bash Scripting Tutorial for Beginners - Linux Tutorials - Learn Linux Configuration
iteration, on Lines 5 the variable counter is incremented by one. Once the variable
counter is equal 3, the condition defined on Lines 4 becomes false and while loop
execution is terminated.
counter=0
while [ $counter -lt 3 ]; do
let counter+=1
echo $counter
done
linuxconfig.org:~$ ./while.sh
1
2
3
linuxconfig.org:~$ vi while.sh
linuxconfig.org:~$ ./while.sh
3
linuxconfig.org:~$
00:00
Until Loop
The last loop we are going to cover in this scripting tutorial is until loop. The until
loop does the exact opposite of the while loop. Until loop also acts on a preset
condition. However, the code enclosed between DO and DONE is repeatedly
executed only until this condition changes from false to true. The execution of until
loop is illustrated using the below example:
https://linuxconfig.org/bash-scripting-tutorial-for-beginners 37/52
11/26/21, 10:49 PM Bash Scripting Tutorial for Beginners - Linux Tutorials - Learn Linux Configuration
1 #!/bin/bash
3 counter=6
5 let counter-=1
6 echo $counter
7 done
If you understood the above while loop script, the until loop will be somewhat self-
explanatory. The script starts with the variable counter set to 6 . The condition
defined on Line 4 of this particular until loop is to keep executing the enclosed
code until the condition becomes true.
counter=6
until [ $counter -lt 3 ]; do
let counter-=1
echo $counter
done
linuxconfig.org:~$ ./until.sh
5
4
3
2
linuxconfig.org:~$ vi until.sh
linuxconfig.org:~$ ./until.sh
3
2
linuxconfig.org:~$
00:00
At this stage, we can convert our understanding of loops into something tangible.
Our current backup script is currently capable to backup a single directory per
execution. It would be nice to have the ability to backup all directories supplied to
the script on a command line upon its execution. Review the updated script below
which implements such a new feature:
1 #!/bin/bash
https://linuxconfig.org/bash-scripting-tutorial-for-beginners 38/52
11/26/21, 10:49 PM Bash Scripting Tutorial for Beginners - Linux Tutorials - Learn Linux Configuration
5 function backup {
7 if [ -z $1 ]; then
8 user=$(whoami)
9 else
10 if [ ! -d "/home/$1" ]; then
13 fi
14 user=$1
15 fi
16
17 input=/home/$user
18 output=/tmp/${user}_home_$(date +%Y-%m-%d_%H%M%S).tar.gz
19
20 function total_files {
21 find $1 -type f | wc -l
22 }
23
24 function total_directories {
25 find $1 -type d | wc -l
26 }
27
28 function total_archived_directories {
30 }
31
32 function total_archived_files {
34 }
35
37
40
https://linuxconfig.org/bash-scripting-tutorial-for-beginners 39/52
11/26/21, 10:49 PM Bash Scripting Tutorial for Beginners - Linux Tutorials - Learn Linux Configuration
43
49
53 ls -l $output
54 else
56 fi
57 }
58
60 backup $directory
61 done;
After reviewing the above script, you may have noticed that new function called
backup on Lines 5 - 57 was created. This function includes all of our previously
written code. The function definition ends on Line 57 after which we have
implemented a new for loop on Lines 59 - 51 to execute the newly defined backup
function for each user directory supplied as an argument. If you recall, the $*
variable contains all arguments supplied on a command line upon the script
execution. Furthermore, a cosmetic change to the code on Line 44 ensures a better
readability of the script's output by separating each directory backup info output
block with a hash line. Let's see how it works:
Files to be included: 27
Directories to be included: 4
Files archived: 27
Directories archived: 4
https://linuxconfig.org/bash-scripting-tutorial-for-beginners 40/52
11/26/21, 10:49 PM Bash Scripting Tutorial for Beginners - Linux Tutorials - Learn Linux Configuration
Files to be included: 3
Directories to be included: 1
Files archived: 3
Directories archived: 1
Exercise:
The current script does not check for the existence of user
directories prior to the backup function execution. This can lead to unforeseen
consequences. Do you think that you would be able to create your own improved
copy of the backup script by defining a separate loop to check the existence of all
user directories before the backup for loop is reached? You for loop will exit the
script's execution if any of the user directories on the supplied list does not exist.
Bash Arithmetics
In the last section of this bash scripting tutorial, we will discuss some basics of bash
arithmetics. Arithmetics in bash scripting will add another level of sophistication
and flexibility to our scripts as it allows us to calculate numbers even with numeric
https://linuxconfig.org/bash-scripting-tutorial-for-beginners 41/52
11/26/21, 10:49 PM Bash Scripting Tutorial for Beginners - Linux Tutorials - Learn Linux Configuration
Arithmetic Expansion
The arithmetic expansion is probably to the most simple method on how to achieve
basic calculations. We just enclose any mathematical expression inside double
parentheses. Let's perform some simple addition, subtraction, multiplication and
division calculations with integers:
linuxconfig.org:~$ a=$(( 12 + 5 ))
linuxconfig.org:~$ echo $a
17
linuxconfig.org:~$ echo $(( 12 + 5 ))
17
linuxconfig.org:~$ echo $(( 100 - 1 ))
99
linuxconfig.org:~$ echo $(( 3 * 11 ))
33
linuxconfig.org:~$ division=$(( 100 / 10 ))
linuxconfig.org:~$ echo $division
10
linuxconfig.org:~$ x=10;y=33
linuxconfig.org:~$ z=$(( $x * $y ))
linuxconfig.org:~$ echo $z
330
linuxconfig.org:~$
00:00
Exercise:
expr command
Another alternative to arithmetic expansion is the expr command. Using the expr
command allows us to perform an arithmetic operation even without enclosing our
mathematical expression within brackets or quotes. However, do not forget to
escape asterisk multiplication sign to avoid expr: syntax error
https://linuxconfig.org/bash-scripting-tutorial-for-beginners 42/52
11/26/21, 10:49 PM Bash Scripting Tutorial for Beginners - Linux Tutorials - Learn Linux Configuration
linuxconfig.org:~$ expr 2 + 2
4
linuxconfig.org:~$ expr 6 * 6
expr: syntax error
linuxconfig.org:~$ expr 6 \* 6
36
linuxconfig.org:~$ expr 6 / 3
2
linuxconfig.org:~$ expr 1000 - 999
1
linuxconfig.org:~$
00:00
let command
Similarly, as with expr command, we can perform bash arithmetic operations with
let command. let command evaluates a mathematical expression and stores its
result into a variable. We have alredy encountered the let command in one of our
previous examples where we have used it to perform integer increment. The
following example shows some basic operations using let command as well as
integer increment and exponent operations like x3 :
00:00
bc command
After few minutes of experimentation with the above bash arithmetic methods, you
may have noticed that they work perfectly with integer numbers however when it
comes to the decimal numbers there is something amiss. To take our bash
arithmetic to an entirely different level, we will need to use bc command. bc
command with a proper syntax allows for more than simple integer calculations.
https://linuxconfig.org/bash-scripting-tutorial-for-beginners 43/52
11/26/21, 10:49 PM Bash Scripting Tutorial for Beginners - Linux Tutorials - Learn Linux Configuration
00:00
Let's put our new bash arithmetic knowledge to work and once again change our
backup.sh script to implement a counter of all archived files and directories for all
users:
1 #!/bin/bash
6 if [ -z $1 ]; then
7 user=$(whoami)
8 else
9 if [ ! -d "/home/$1" ]; then
12 fi
13 user=$1
14 fi
15
16 input=/home/$user
https://linuxconfig.org/bash-scripting-tutorial-for-beginners 44/52
11/26/21, 10:49 PM Bash Scripting Tutorial for Beginners - Linux Tutorials - Learn Linux Configuration
17 output=/tmp/${user}_home_$(date +%Y-%m-%d_%H%M%S).tar.gz
18
19 function total_files {
20 find $1 -type f | wc -l
21 }
22
23 function total_directories {
24 find $1 -type d | wc -l
25 }
26
27 function total_archived_directories {
29 }
30
31 function total_archived_files {
33 }
34
36
39
42
48
52 ls -l $output
53 else
https://linuxconfig.org/bash-scripting-tutorial-for-beginners 45/52
11/26/21, 10:49 PM Bash Scripting Tutorial for Beginners - Linux Tutorials - Learn Linux Configuration
55 fi
56 }
57
59 backup $directory
60 let all=$all+$arch_files+$arch_directories
61 done;
On Line 60 we have used addition to add all archived files using let command to a
resulting variable all . Each for loop iteration adds new count for every additional
user. The result is then printed using echo command on Line 62 .
Files to be included: 27
Directories to be included: 6
Files archived: 27
Directories archived: 6
Files to be included: 3
Directories to be included: 1
Files archived: 3
Directories archived: 1
Exercise:
Experiment with the backup.sh script. The script is far from being
perfect, add new features or fix current features. Do not be afraid to break things
as that is perfectly normal. Troubleshooting and fixing code is perhaps the best
https://linuxconfig.org/bash-scripting-tutorial-for-beginners 46/52
11/26/21, 10:49 PM Bash Scripting Tutorial for Beginners - Linux Tutorials - Learn Linux Configuration
booster for you to enhance your understanding of bash scripting and to improve
your ability to script beyond what has been discussed in this tutorial.
Conclusion
There is more to bash shell scripting than covered in this tutorial. However, before
you move on, make sure that you are comfortable with topics discussed here. Apart
from googling, there are myriad of other resources available online to help you out if
you get stuck. The most prominent and highly recommended of them all is GNU's
Bash Reference Manual.
https://linuxconfig.org/bash-scripting-tutorial-for-beginners 47/52
11/26/21, 10:49 PM Bash Scripting Tutorial for Beginners - Linux Tutorials - Learn Linux Configuration
Excellent tutorial.
For a guy who knows about about scripting you have done me the world of good.
I agree with the previous comments, very well written and explained.
If you are looking to expand it, could I suggest working through file handling - copying,
moving, naming, renaming, removing/extracting file extensions etc.
We have a very heavily scripted workflow here using Applescript and it’s virtually all to
do with file handling. I’d love to have a go at rewriting some of it into shell scripts.
I can’t get over how well you presented bash scripting to new users. Simply a
remarkable write-up! You started off at the foundations of the CLI and built up to more
advanced concepts very comfortably. I’ve tried to do the same for some users IRL but
I’m just going to share this instead:)
1 reply
Lubos
Moderator ▶ AutoPublisher Jun '18
Thank you for an incredibly motivating feedback. I had a pleasure to teach Bash
Scripting to beginner students at the local university for more than six years. Perhaps
https://linuxconfig.org/bash-scripting-tutorial-for-beginners 48/52
11/26/21, 10:49 PM Bash Scripting Tutorial for Beginners - Linux Tutorials - Learn Linux Configuration
this gave me a little bit of insight on how to present the material and avoid hurdles at
the same time.
Writing tutorials for beginners is much harder than writing advanced topic tutorials for
advanced users. That much is clear. In any case, I still consider the work on this
tutorial as “ongoing” thus as version 1.0.0. I will wait for any other additional feedback
from readers, and if needed, I will update it accordingly.
link
Depending on what the comparison result is, I output a message for the output
fil d th id th f il
https://linuxconfig.org/bash-scripting-tutorial-for-beginners Ih tf d i ith th 49/52
11/26/21, 10:49 PM Bash Scripting Tutorial for Beginners - Linux Tutorials - Learn Linux Configuration
file and thus avoid the failure message. I have not found an issue with the
directories comparison.
Cheers!
moonshiner45
1 reply
sandmann
Moderator ▶ moonshiner45 Dec '20
Hi Moonshiner45,
NEWSLETTER
Subscribe to Linux Career Newsletter to receive latest news, jobs, career advice and featured
configuration tutorials.
SUBSCRIBE
WRITE FOR US
LinuxConfig is looking for a technical writer(s) geared towards GNU/Linux and FLOSS
technologies. Your articles will feature various GNU/Linux configuration tutorials and
FLOSS technologies used in combination with GNU/Linux operating system.
When writing your articles you will be expected to be able to keep up with a technological
advancement regarding the above mentioned technical area of expertise. You will work
independently and be able to produce at minimum 2 technical articles a month.
APPLY NOW
CONTACT US
web ( at ) linuxconfig ( dot ) org
TAGS
https://linuxconfig.org/bash-scripting-tutorial-for-beginners 50/52
11/26/21, 10:49 PM Bash Scripting Tutorial for Beginners - Linux Tutorials - Learn Linux Configuration
TAGS
18.04
administration
apache
applications
bash
beginner
browser
centos
centos8
commands
database
debian
desktop
development
docker
fedora
filesystem
firewall
gaming
gnome
Hardware
installation
java
kali
manjaro
multimedia
networking
nvidia
programming
python
redhat
rhel
rhel8
scripting
security
server
ssh
storage
terminal
ubuntu
ubuntu 20.04
video
virtualization
webapp
webserver
FEATURED TUTORIALS
How to install the NVIDIA drivers on Ubuntu 20.04 Focal Fossa Linux
How to install Tweak Tool on Ubuntu 20.04 LTS Focal Fossa Linux
How to Install Adobe Acrobat Reader on Ubuntu 20.04 Focal Fossa Linux
How to install the NVIDIA drivers on Ubuntu 18.04 Bionic Beaver Linux
Nvidia RTX 3080 Ethereum Hashrate and Mining Overclock settings on HiveOS Linux
https://linuxconfig.org/bash-scripting-tutorial-for-beginners 51/52
11/26/21, 10:49 PM Bash Scripting Tutorial for Beginners - Linux Tutorials - Learn Linux Configuration
LATEST TUTORIALS
How to perform administration operations with Ansible modules
How to tune Linux extended (ext) filesystems using dumpe2fs and tune2fs
https://linuxconfig.org/bash-scripting-tutorial-for-beginners 52/52