Bash scripting tutorial — Part 1

Bash scripting is essential to any system administrator or DevOps engineer; bash scripting allows automating tasks that can be tedious…

Bash scripting tutorial — Part 1
Photo by Gabriel Heinzer on Unsplash

Bash scripting is essential to any system administrator or DevOps engineer; bash scripting allows automating tasks that can be tedious, error-prone, and boring.

In this part, we will cover the following topics of bash scripting.

  • Printing on screen
  • Variables
  • Difference between global and local variables
  • How to pass arguments to a bash script
  • Executing commands within a script and assigning results to a variable
  • Reading keyboard input
  • Arrays and how to loop them

Hello World

Every tutorial starts with a “Hello World” printed on the screen, so why should this be an exception? Save the following file as hello_world.sh

#!/bin/bash 
echo "Hello World"

Make the file executable

$ chmod +x ./hello_world.sh

Run the script

$ ./hello_world 
Hello World

Congratulations, you just created your first bash script that prints something on the screen.

Variables

Edit the script to match the following

#!/bin/bash 
MY_VAR="Hello world!!!" 
echo $MY_VAR

We stored the characters “Hello world!!!” to variable MY_VAR and then printed the variable on screen.

Run the script again

$ ./hello_world 
Hello World!!!

A variable in bash is declared like this

VAR="VALUE"

And accessed like this, notice the $ symbol before the variable

echo $VAR

Global vs local variables

In bash a global variable is a variable that can be used anywhere inside the script, a local one is limited to the scope of a function is used.

Save the following as vars_example.sh

#!/bin/bash 
 
my_var="This is a global variable" 
 
function my_func { 
 local my_var="This is a local variable" 
 echo $my_var 
} 
echo $my_var 
my_func 
echo $my_var

Make it executable and run the script

$ chmod +x ./vars_example.sh 
$ ./vars_example.sh 
This is a global variable 
This is a local variable 
This is a global variable

What just happened? at the start of the script, the variable my_var had been declared. We created a function that uses the local keyword to declare a local variable that happens to have the same name as the global variable but the scope of the local variable is only within the function any change to the local variable does not affect the contents of the global variable which just happens to share the same name.

How to pass arguments to the script

One way of passing arguments to a bash script is to use positional parameters; this means that the parameters will come from the shell as they are typed, and each parameter will be comma separated except using quotes.

Save the following content as args_example.sh and make it executable

#!/bin/bash 
 
echo $1 $2 $3

Run the script with the following parameters

$ ./args_example.sh a b c d 
a b c

Notice that it printed only the first three parameters despite we provided four; this is normal since we echo only $1 $2, and $3

If we run the same program by quoting the last two characters, “c d” it will print d as well, but this is because $3 holds now 3 characters, c, space and d

$ ./args_example.sh a b "c d" 
a b c d

Arguments can also be accessed as an array; save the following as array_args.sh

#!/bin/bash 
echo $@ 
echo $#

Execute it with the following parameters

./array_args.sh 1 2 3 
1 2 3 
3

It printed the array of the arguments and the second line the length of the array.

To access each argument of the array, modify the file to match this content.

#!/bin/bash 
echo "${0}" 
echo "${1}"

Executing this with the following parameters will print the script file name and the first argument; this happens because the first element of the arguments is always the script filename.

./array_args.sh 1 2 3 
./array_args.sh 
1

Executing shell commands within a script

Create the following script and save it as exec_cmds.sh; the following script uses $( ) to execute shell commands, $( ) creates a sub-shell, executes the command, and returns the output.

#!/bin/bash 
h=$(hostname) 
echo $h

the hostname command returns the computer name, which in my case is ‘nautilus’.

$ ./exec_stuff.sh 
nautilus

Reading keyboard input

In some cases, your script might need to read input in an interactive manner, like responding to a prompt. create the following file and save it as kb_input.sh

#!/bin/bash 
echo -e "Type one word: \c" 
read var1 
echo "Word was $var1"

Run the script, and when the prompt appears to input some output, you will see the output printed on the screen.

$ ./kb_input.sh 
Type one word: Hello 
Word was Hello

We can input even input to two variables in the same prompt, modify the script to match the following

#!/bin/bash 
echo -e "Type two words: \c" 
read var1 var2 
echo "Words were $var1 and $var2"

Run the script again and now provide two words, space-separated.

$ ./kb_input.sh 
Type two words: kostas patronas 
Words were kostas and patronas

Finally, we can store keyboard input to an array; and modify the script to match the following.

#!/bin/bash 
echo -e "Type three words: \c" 
read -a words 
echo "Words were ${words[0]}, ${words[1]} and ${words[2]}"

Then run the script and provide three arguments

$ ./kb_input.sh 
Type three words: a b c 
Words were a, b and c

Arrays and how to loop them

Its very easy to create an array in bash, create the following file and save it as array_loop.sh

#!/bin/bash 
 
ARRAY=('element1' 'element2' 'element3') 
for element in ${ARRAY[@]}; 
do 
   echo ${element} 
done

ARRAY is the name of our variable and everything between (...) are the elements of the array, the elements must be space separated.

In the for statement, we ask bash to loop each element of ARRAY variable, the @ symbol in the square brackets indicates that we are looping all the elements in the array.

We can even slice an array to exclude a range of elements from the loop, modify the code script to match this

#!/bin/bash 
 
ARRAY=('element1' 'element2' 'element3') 
for element in ${ARRAY[@]:1:2}; 
do 
   echo ${element} 
done

Now rerunning the script will exclude the first element since we sliced the array by excluding the first element

$ ./array_loop.sh 
element2 
element3

If the length of the array is unknown we can do the following trick

#!/bin/bash 
 
ARRAY=('element1' 'element2' 'element3') 
for element in ${ARRAY[@]:1}; 
do 
   echo ${element} 
done

In this example, we set as starting index the second element, and none parameter as last

$ ./array_loop.sh 
element2 
element3

Now assuming that we want to print a range of the array but we want to define both the starting and the stop indexes, write the following; inthis example, we have three elements, and we have the second one as a starting point in index position “1” (remember arrays start counting from zero) and as ending point is the length of the array (3) minus 2 to provide the index of the second element.

The expr command allows doing math between variables.

#!/bin/bash 
 
ARRAY=('element1' 'element2' 'element3') 
start_index=1 
stop_index=$(expr ${#ARRAY[@]} - 2) 
 
for element in ${ARRAY[@]:$start_index:$stop_index}; 
do 
   echo ${element} 
done

Executing this script outputs only the second element of the array, just as we asked

$ ./array_loop.sh 
element2

Conclusion

I hope you found the explanations easy to read and understand; in the next part, we will cover other aspects like flow control using if;then;else; variable comparisons and file testing.

Join Medium with my referral link - Konstantinos Patronas
As a Medium member, a portion of your membership fee goes to writers you read, and you get full access to every story…