Skip to main content

Command Palette

Search for a command to run...

Shell/Bash Scripting - Let's write our first Bash Script

Bash Scripting for DevOps with resources

Updated
16 min read
Shell/Bash Scripting - Let's write our first Bash Script

Pre-Requisites to learn Bash/Shell Scripting:

  • Linux basics

  • Command line basics

  • No programming knowledge required

What is a Kernel?

Interface between hardware and software

What is a Bash/Shell?

  • Bash: A command language interpreter used for interacting with a computer from the command line.

  • It is like a container

  • The interface between users and Kernel

  • Also Known As Commonly referred to as "the shell."

  • CLI is a shell

  • Purpose:

    • Provides a user-friendly interface to interact with the operating system.

    • Hides the complex details of the operating system kernel.

    • Enables tasks such as accessing data and writing files through simple commands.

  • Historical Significance:

    • Introduced in the early 1970s.

    • Revolutionized how users interact with computers.

  • When you open any operating system like macOS or Linux's any distro like Ubuntu the default Shell is usually Bash.

  • Bash is also a programming language that allows us to write scripts which means anything we manually type into the command line can be automated with code.

Find your Shell

  •       echo $0
    
  • Available Shells “cat /etc/shells”

      cat /etc/shells
    
    • Your Shell? /etc/passwd
    cat /etc/passwd
  • Windows GUI is a shell

  • Linux KDE(K Desktop Environment.) GUI is a shell

  • Linus sh, bash, etc. is a shell

What is Bash/Shell Scripting?

A bash script is a file that contains one or more commands that are meant to be executed within your bash shell.

Why Shell Scripting?

Shell scripts in Linux are an easy-to-use time-saving solution for automating repetitive or complex sets of tasks in a system administrator’s daily life. It can help save time and increase productivity, so it’s a must-have skill for anyone working on computers.

  • Automate daily backups

  • Automate installation and patching of software on multiple servers

  • Monitor system periodically

  • Raise alarms and send notification

  • Troubleshooting and Audits

  • Many more

Types of Linux Shell

Below both of these are the desktop GUI environment

  • Gnome

  • KDE (K Desktop Environment)

CLI environment:

  • sh - So, this just sh is a Bourne shell called sh, one of the original Linux shells. It is developed by Unix computers by Stephon Bourne. He worked for AT&T Labs in 1977. It offers features such as:

    • input and output redirection

    • shell scripting with string

    • integer variable and condition testing and looping etc…

  • bash - It means Bourne again shell so it

  • csh and tcsh - used specifically in cases if you are proficient with c/c++ languages. tcsh doesn’t run bash.

  • ksh - KornShell( developed by David Korn). Korn shell is compatible with shell and bash shell as well. Korn Shell improves on Bourne Shell by adding floating point automatic job control.

Best practice to follow:

  • Give your script a name that makes sense.

  • Design your script to be reusable

  • The script should not require to be edited before running

  • Use command line arguments to pass inputs.

  • For example(good naming) create-and-launch-rocket

  • Bad Naming: script1.sh, myscript2.sh, test.sh, etc…

  • Leave out .sh extension for executables:

  • good: create-launch-rocket

  • bad: create-launch-rocket.sh

Writing our first bash script:

#!/bin/bash

# A script that will print out a message

echo 'Hello Bash bro'
  • #!/bin/bash: this line is called a ‘shebang’. This is the line from where the script starts to execute.

  • (hashtag or pound or number sign) !(exclamation mark) These together mean that hey, this is a shebang.

  • Shebang is used to tell the environment we’re in, and which interpreter we will be using.

  • In this case, since the shebang is /bin/bash, we’re telling it, hey, we’re going to use bash which makes sense because this is a bash shell.

  • #message: with # (comment) is used to document your script, and provide clarity in context to what you’re creating here/what our program will do.

  • echo ‘Hello Bash bro’: to print the output.

How to execute a script

  • First, make a file with the name you like. e.g.

      vi myscript
      OR
      vim myscript
    
  • Give you file permission to execute:

      chmod a+x myscript
      # here a means to all users and x means execute
    
  • Execute Script Directly:

    Run ./myscript to execute the script.

What is a variable and how do we use them

A variable is a way to store data and use it within our bash script.

Why would you want to do this?

  • Well, it makes us more efficient because we’re repeating less code.

Variable - whose values can change

Constants - whose value can not change

  • Variable only contain Alphanumeric OR Underscores

  • And it’s Case Sensitive as well

Best practices:

  • good one: mission_name

  • bad one: Mission_Name, Mission Name, Mission-name

#!/bin/bash

# This is when we assign value to a variable
hello_message='Hello, world!'

# If we want to print the current directory along with the message 
current_dir=$(pwd)

#  And this is when we are using variable
echo "$hello_message from $curret_dir"

What are the positional arguments/parameters in shell scripting?

The positional parameters hold the arguments passed to a script or function. They are referenced using $1, $2, $3, etc., where $1 is the first argument, $2 is the second, and so on. $0 refers to the script's name.

Example script:

#!/bin/bash 

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

If the script is executed with ./myscript arg1 arg2,
it will output: First argument: arg1 Second argument: arg2

How to accept user input

#!/bin/bash

echo Hello, My name is Suraj.
echo
echo What is your name?
echo 
read broname
echo
echo Hello $broname

read -p "Enter mission name:" variable_name
echo $variable_name

# read take the input 
# -p display the text

What are the conditional statements in bash?

Conditionals are just if else statements we can understand by the below example:

A simple if-then code in bash

#!/bin/bash

number=25

if [ $((number % 2)) -eq 0 ];
then
   echo "The number $number is even!";
else 
   echo "The number $number is odd!"
fi
#!/bin/bash

clear

if [ -e /home/devopsbro/basicbashscript/bro.txt ]

                then
                echo "File exists"
                else
                echo "File does not exist"
fi

What are Case Statements in Bash?

Most of the installation programs are written in case statements where the scripts wait for user input to select from choices.

#!/bin/bash

# A script that will ask for a number and print out a message depending on the value. 

read -p "Enter a value: " n
case $n in
    ???) 
        echo "One";;
    2) 
        echo "Two";;
    aa) 
        echo "Three";;
    *.txt) 
        echo "Four";;
    *) 
        echo "Other";;
esac

# read: it is the command to ask the user to provide a number

# -p: allows us to provide a prompt which in this case is enter a value

# n: name of the variable

What are loops in Bash?

  • Program to automate the repeating task

  • Here we are learning to do while done keywords

While loop

#!/bin/bash

# A script to display a series of numbers using a while loop.

counter=1
# here ‘ -le ‘ is less then
while [[ "$counter" -le 10 ]]; do
    echo "The counter is at: $counter"
    counter=$((counter + 1))
done
echo "The count has finished."

Until loop

#!/bin/bash

# A script to display a series of numbers using while.

counter=1
until [[ "$counter" -gt 10 ]]; do
    echo "The counter is at: $counter"
    counter=$((counter + 1))
done
echo "The count has finished."

for loop traditional

#!/bin/bash

# Print values in an array using for loops

services=("loadbalancer" "virtualmachine" "storage")

# here @ mean all the elements of the array services
for i in "${services[@]}"
do
   echo $i
done

for loop new

#!/bin/bash

# A script to display a series of numbers using a for loop.

for (( i=0; i<5; i=i+1 )); do
    echo "The counter is at: $i"
done

loop and break

#/bin/bash

# A script that will recieve input and break depending on condition. 

while true; do
# here n is variable that store the user input
  read -p "Enter a number between 1 and 25: " n
  if [[ $n -ge 1 && $n -le 25 ]]; then
    echo "You entered $n"
  else 
    echo "You didn't enter a number in range, goodbye."
    break
  fi
done
echo "Break happened"
# the ‘fi’ here is the opposite of ‘if’ to stop if statement

What are the functions in bash?

A function in Bash is a reusable block of code that can be called with a name to perform a specific task, defined using the syntax function_name() { commands; }.

#!/bin/bash

# function name and definition
check_even () {
    local mod=2
    echo "The value of mod is $mod"
    if [ $(("$1" % $mod)) -eq 0 ]
    then 
       echo "The number $1 is even!";
    else 
       echo "The number $1 is odd!"
    fi
}
# Variable Declaration
number=2344

# Function Call
check_even $number
echo $mod

local: It is a scope here which means whatever is defined inside the function which {} can’t access outside but only inside.

Check Remote Servers Connectivity

A script to check the status of remote hosts

#!/bin/bash

# this is a simple script
ping -c1 192.168.1.1
        if [ $? -eq 0 ]
        then
        echo OK
        else
        echo NOT OK
        fi

# Change the IP to 192.168.1.235
#!/bin/bash

# This is a good one
# Don't show the output
ping -c1 192.168.1.1 &> /dev/null
        if [ $? -eq 0 ]
        then
        echo OK
        else
        echo NOT OK
        fi
#!/bin/bash

# This is the better one
# Define variable

hosts="192.168.1.1"
ping -c1 $hosts &> /dev/null
        if [ $? -eq 0 ]
        then
        echo $hosts OK
        else
        echo $hosts NOT OK
        fi

# Change the IP to 192.168.1.235
#!/bin/bash

#Multiple IPs
IPLIST="path_to_the_Ip_list_file"


for ip in $(cat $IPLIST)

do
   ping -c1 $ip &> /dev/null
   if [ $? -eq 0 ]
   then
   echo $ip ping passed
   else
   echo $ip ping failed
   fi
done

Aliases(alias)

In real life, aliases are short names of long ones to remember.

Aliases is a very popular command that is used to cut down on lengthy and repetitive commands

# Here are the some example of how you can make an alias of any command

alias ls="ls -al"
alias pl="pws; ls"
alias tell="whoami; hostname; pwd"
alias dir="ls -l | grep ^d"
alias lmar="ls -l | grep Mar"
alias wpa="chmod a+w"
alias d="df -h |awk '{print \$6}' | cut -cl-4"

Note: {print \$6} here before $6, we put backslash “\” because we don't want Linux to not think of $6 as a variable.

  • To know what and how many aliases you have made use the command alias to know.

  • To delete an alias

      unalias nameOfAlias
    
  • To delete all the aliases at once

      unalias -a
    

User and Global Aliases

Creating User or Global Aliases.

  • User = Applies only to a specific user profile

      User = /home/user/.bashrc
    
  • Global = Applies to everyone who has an account on the system

      Global = /etc/bashrc
    

Note: So basically if we are creating an alias in the terminal without user-specific then it’ll stay only for that session and when you close and open the terminal you’ll not find the alias again. So to solve this we’ll be creating a user alias:

Now let's make the alias Global:

for me, this command works to add a global alias

sudo nano /etc/bash.bashrc

Shell History

You can know all the commands that you have run in your terminal by just running the command history .

history

If you want to scroll more command of history just run this command:

history | more

If you want to run any command from you history just remember the number of that command left side and run it this way:

!8

Note: The file where the history of your shell commands is saved and to know that run the below command:

/home/username/.bash_history

The Linux commands you'll use while working with Bash

  1. ls --help : To know more about ls command.

  2. echo --help : To know more about echo command.

  3. man : An interface to the system reference manuals.

  4. pushd : Adds a directory to the directory stack.

  5. popd : Removes a directory from the stack and changes to it.

  6. mkdir foldername : Create the folder with the name specified.

  7. mkdir -p suraj1/suraj2/suraj3 : For creating parent directories.

  8. touch filename : To create a file.

  9. mv source_name destination_name : Used to move or rename files and directories from source_name to destination_name .

  10. cp source_name destination_name : Copies source_name to destination_name, creating a duplicate file or directory.

  11. rm file_name_you_want_to_delete : Used to remove files or directories.

  12. rm -r file_name_you_want_to_delete : For recursive deletion

  13. rmdir directory_name : Used to delete

  14. cat file_name : Used to view to content of the file.

  15. head file_name : This will display by default the first 10 lines of your content.

  16. head -n 5 file_name : Now this will display the first 5 number of lines of your content because we have specified it using the ‘-n’ flag.

  17. tail file_name : This will display by default the last 10 lines of your content.

  18. tail -n 5 file_name : This will display the last 5 number of lines of your content.

  19. more file_name : It will give the information page by page. and hit the space bar to go page by page.

  20. less file_name : ‘less’ and ‘more’ are very similar just the less has a lot more options in its navigation.

  21. grep --help : To know more about grep

Use of Wildcards:

  • To find any files with an asterisk(*) and with ??:

  • To print all the files with the uppercase and lowercase as well:

How to use ‘whereis’ command:

whereis file_name
whereis -b file_name
which file_name

How to use the find command:

find . -name "*.md"

The above command says to find in the current directory(.) all the name which has the .md extension

find /home -name file.txt
find /home -iname file.text

So here I mean it’ll remove the case sensitivity and show all the files whose name is file.txt regardless if it is in lowercase or uppercase

find . -type d

How to use the environment variables command:

As the name suggests the environment variables set several variables for your shell environment. Environment variables are important because applications, command line tools, and shell scripts use them to determine their configuration.

  • Knowing how to view, create, and modify environment variables is a must if you were to learn the ways of the terminal.

The ‘env’ command:

this command will show you all the environment variables that are available currently.

env
  • If we want to see just a single environment variable, we can use the ‘echo’ command:

These are the environment variables:

echo $SHELL
# OUTPUT: /bin/bash
echo $HOME
# /home/user
echo $USER
# user
echo $PATH
# (example): /home/devopsbro/.nvm/versions/node/v20.15.0/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/snap/bin

The command to create an environment variable is ‘export’:

export --help : To know more about export command.

export newVar=value
echo $newVar

# output: value

Important: The environment variable that we just created is only for the current session. And the question comes in :

“How do you persist environment variables across sessions?”

and “the answer to this question is what bash calls startup files.”

  • So there are several locations for the startup files but two worth mentioning are the ‘global configuration’ which is located under the ‘etc’ profile, and if you were to make changes to this particular file, it would affect every user logged in to the machine or their bash session for every user logged in the machine.
ls /etc/profile
  • Another one is the ‘.’ profile which exists underneath the user’s home directory
ls -a ~

# it will output: .bashrc or .profile kind of profiles

How to use Redirection:

Everything that you see on the terminal either comes from an output stream or an input stream. In bash, you can redirect or chain together that output using the redirection operator and the pipeline.

  • One of the streams that command right to is the standard output:

      ls - l
    
  • Using redirection operator now:

      ls -l > file_name.txt
    
  • If you want to put the new content in a new like you want to append:

      touch file_name.txt
      ls -l >> file_name_in_which_you_want_to_apppent.txt
    

Standard error:

ls -l ./dir

# This will give an error

Here 2 is the file descriptor that indicates the standard error, and so it’s saying redirect standard error to this particular location.

ls -l ./dir 2> error.txt

Now, this is without a file descriptor:

ls -l ./dir > error.txt

# It just redirects to the terminal because I'm not redirecting standard error, I am trying to redirect the standard output

So here 2>&1 in this we’re saying stream one and stream two redirects to these files.

ls -l ./dir > error.txt 2>&1
or 
ls -l &> error.txt 

# The above two commands are the same as long as we're doing this is in the same directory but not append.

If we want to append we can do this:

ls -l >> error.txt 2>&1

How to use pipelines ( | ):

This is without the pipe symbol

ls -l /usr/bin

as we know what less command do this will show the content less and we can scroll using the spacebar

ls -l /usr/bin | less

This will find the echo in this directory

ls -l /usr/bin | grep echo

This will find and sort the content

ls -l /usr/bin | grep echo | sort

This will show the first content of this file.

ls -l file_name.txt | head -n 1

This will show the last line of the file.

ls -l file_name.txt | tail -n 1

How to modify file permissions in Bash:

How to view permissions:

ls -ltr or
ls -l

Command to change the owner for Ubuntu users:

sudo chown root file_name.txt
# Here chown is the command and root is the new owner and the file name whose owner you want to change.
sudo chown :root file_name
# This command is used for changing the group owner
chgrp owner_name_you_want_change file_name
# This is the another command to change the group owner

How to use the chmod command:

This command will add the execute permission to the file for user, group, and other

chmod +x file_name
chmod 444 file_name
# The 444 means here in the user,group,and other it will give permission to execute the file.

Afterward, executing ls -l file_name might show something like:

-r--r--r-- 1 user group 1234 Jul 9 10:00 file_name

This table will help you to understand better:

Octal NumberPermissionsMeaning
0---No permissions
1--xExecute only
2-w-Write only
3-wxWrite and execute
4r--Read-only
5r-xRead and execute
6rw-Read and write
7rwxRead, write, and execute

Best Resources from where I learned

YouTube Video Resources:

  1. Bash in 100 Seconds By Fireship

  2. Shell Scripting Zero To Hero || Shell Scripting for Devops & Cloud || Shell scripting for Beginners

  3. Welcome to Bash for Beginners [1 of 20] | Bash for Beginners

Thanks for reading guys

DevOps

Part 9 of 14

In this series I'll share all my learning and experiences of Cloud/DevOps & Cloud-Native. Access website here: https://devops.devsuraj.me

Up next

Computer Networking Course: How does the internet work?

Networking for DevOps