Shell scripting consists of set of commands to perform a task.
Different types of shells:
- bash
- sh
- ksh
- tsh
- fish
- zsh (Extended version of bash with more advanced features)
What is my shell type?
echo $0
How to check supported shells?
cat /etc/shells
What is shebang?
It specifies which interpreter should be used to execute the script.
#!/bin/bash
Basic shell script
#!/bin/bash
echo "hello world!"
How to execute script?
Make sure script have execute permission rwx.
1- ./file.sh
2- path/file.sh
3- bash file.sh
How to add comments?
1- single line comment
#comment
2- Multiline comment
<<comment
---- Your Comment Here ----
comment
Variables:
How to use variables?
#!/bin/bash
person="Arbab Anjum"
hostName=$(hostname)
readonly role="superadmin"
echo $person is using $hostName and role is $role
------
> Output: Arbab Anjum is using ubuntu and role is superadmin
Array:
How to define and get value of an array?
Set Value:
myArray = (1 2 3 Hello "World");
Get Value:
echo "${myArray[0]}"
echo "${myArray[1]}"
How to find length of an array?
echo "${#myArray[*]}"
How to get specific values?
echo "${myArray[*]:1}"
echo "${myArray[*]:1:2}" // from index 1, get 2 values
How to update an array?
myArray+=(New 7 8)
How to store the key value pairs?
declare -A myKeyValArray
myKeyValArray=([name]="Arbab Anjum",[city]="London")
echo "Name is ${myKeyValArray[name]}"
String Operations:
myVar="My name is Muhammad Arbab Anjum"
echo "Length: ${#myVar}"
echo "Uppercase: ${myVar^^}"
echo "Length: ${myVar,,}"
echo "Replace (name) with (Name): ${myVar/name/Name}"
echo "Slice: ${myVar:6:13}"
User Interaction:
echo "What is your name? "
read name
echo "Name is $name"
read in same line:
read -p "What is your name: " name
echo "My name is $name"
Arithmetic Operations
x=10
y=2
let mul=$x*$y # use 'let' to tell it's a mathematical operation
echo "Multiplication: $mul"
echo "Addition: $(($x+$y))"
Conditional Statement
If Else
Example: 1
if [[ $marks -gt 40 ]]
then
echo "Pass!"
else
echo "Fail!"
fi
Example: 2
if [[ $marks -gt 40 ]]
then
echo "Above 40!"
elif [[ $marks -eq 30 ]]
echo "Fail!"
then
echo "Equal 30!"
else
echo "Less than 30!"
fi
Example: 3 || Logical operation
if [[ $age -gt 18 ]] && [[ $country -eq "London" ]]
then
echo "Pass!"
else
echo "Fail!"
fi
Equal > -eq/==
Greater than or equal to > -ge
Less than or equal to > -le
Not equal to > -ne/!=
Greater than > -gt
Less than > -lt
Switch Case
echo "Choose an option below:"
echo "a = To see current data"
echo "b = list all files in current directory"
read choice
case $choice in
a) date;;
b) ls;;
*) echo "Not a valid input"
esac
For Loop
Example: 1
for i in 1 2 3 4 5
do
echo "Number: $i"
done
Example: 2
for i in {1..10}
do
echo "Number: $i"
done
Example: 3 - Getting value from file name.txt
FILE='/home/arbab/name.txt'
for name in $(cat $FILE)
do
echo "Name is: $name"
done
Example: 4 - Getting value from file name.txt
myArray=(1 2 3 4 5 6 7)
for (( i=0; i<${#myArray[*]}; i++ ))
do
echo "Value is: ${myArray[$i]}"
done
while Loop
Code keeps executing till the statement is true
count=0
num=10
while [ $count -le $num ]
do
echo "Number: $count"
let count++
done
Until loop
Code keeps executing till the statement is false
a=10
until[ $a -eq 1 ]
do
echo "Number: $a"
let a--
done
Read content from CSV file
while IFS="," read f1 f2 f3
do
echo "$f1"
echo "$f2"
echo "$f3"
done < file_name.csv
Function
Example 1:
function myFun{
echo "--------"
echo "Welcome"
echo "--------"
}
# Calling Function
myFunc
Example 2:
myFun(){
echo "--------"
echo "Welcome"
echo "--------"
}
# Calling Function
myFun
Example 2: With arguments
#!/bin/bash
myFun(){
local num1=$1 # $1-> First argument: 5
local num2=$2 # $2-> Second argument: 2
let result=$num1+$num2
echo "--------"
echo "Sum: $result"
echo "--------"
}
# Calling Function
myFun 5 2
Example 2: Send arguments while executing file
./file.sh arbab anjum
file.sh:
echo $1 # result: arbab
echo $@ # result: arbab anjum -> $@ means all arguments
echo $# # result: 2 -> number of arguments
Useful Concept
- break - To stop the loop
- continue - To stop current iteration of loop and start from the next iteration
- sleep - To create delay between two execution e.g; sleep 1m/1s
- exit - To stop script to a point. e.g; exit 1
- $? - exit status - gives you status of previous command if that was successful - status 0 means success
- basename - strip directory info and only give filename
- dirname - strip the filename and gives dir path
- realpath - gives you full path for a file
- RANDOM - generate random number - echo $RANDOM
- UID - User ID of the logged in user - echo $UID - UID of root user is 0
Debugging:
Add `set -x` in the script to enable debugging
Scripts:
Check if file exist or not
#!/bin/bash
FILPATH=/home/test/file.csv
if[[ -f $FILEPATH ]]
then
echo "FILE EXIST"
else
echo "FILE DON't EXIST"
fi
If you want to exit script when a command fail
set -e # use this
echo "Hello"
cd /root #fail and skip next execution
pwd
Run script in background
nohup ./script.sh
Run Script at specific time using At command
at 12:09 AM # Run and hit enter it will ask what to do
bash ./script.sh
atq -> to check scheduled job
atrm <id> -> to remove a scheduled job
Crontab - Script automation
crontab -l # view existing cronjobs
crontab -e # Create New
Format:
* * * * * cd /home/arbab/ && ./runfile.sh
Stars from Right To Left
* -> Day of Week (0-6) Sunday=0
* -> month 1-12
* -> Day of month (1-31)
* -> hour 0-23
* -> minute 0-59
https://crontab.guru
Mini Projects
Monitoring free RAM Space
#!/bin/bash
FREE_SPACE=$(free -mt | grep "Total" | awk '{print $4}')
TH=500
if [[ $FREE_SPACE -lt $TH ]]
then
echo "Normal Memory!"
else
echo "Running out of memory!"
fi
#--------- Comments ---------
#free -mt -> show total free memory
#grep "Total" -> pick the line containing word total
#awk '{print $4}' print 4th column value
Monitoring free disk Space and send an alert email
#!/bin/bash
FREE_DISK_SPACE=$(df -H | egrep -v "Filesystem|tmpfs" | grep "sda2" | awk '{print $5}' | tr -d %)
TH=90
[email protected]
if [[ $FREE_DISK_SPACE -lt $TH ]]
then
echo "Disk has enough space!" | mail -s "Disk Space Alert" $TO
else
echo "Low disk space!"
fi
#--------- Comments ---------
#configure postfix to send emails
#df -h -> show all disk usage
#egrep -v "Filesystem|tmpfs" -> Remove Filsystem and tmps line from output
#grep "sda2" -> search sda2
#awk '{print $5}' print 5th column value
#tr -d % -> truncate/delete % from output
Move files having size more than 20MB to achieve folder
!/bin/bash
# Version: 1
# Date: 19 April 2025
#Variables
BASE=/home/arbab/myFiles
DAYS=10
DEPTH=1
RUN=0
#check if the directory is present or not
if [[ ! -d $BASE ]]
then
echo "Dir doesn't exist: $BASE"
exit 1
fi
#create 'archive' folder if not present
if [[ ! -d $BASE/archive ]]
then
mkdir archive
fi
#Find list of files largest than 20MB
for i in `find $BASE -maxdepth $DEPTH -type f -size +20M`
do
if [[ $RUN -eq 0 ]]
then
echo "[$(date "+%y-%m-%d %H:%M:%S")] archiving $i ==> $BASE/archive"
gzip $i || exit 1
mv $i.gz $BASE/archive || exit 1
fi
done
## || runs the command on right side when left side result is false
Automate user account creation
#!/bin/bash
# script should execute with sudo/root access.
if [[ "${UID}" -ne 0 ]]
then
echo 'Please run with root or sudo user'
exit 1
fi
# user should provide atleast one argument as username else guide him
if [[ "${#}" -lt 1 ]]
then
echo 'Usage: ${0} USER_NAME [COMMENT]...'
exit 1
fi
# ${0} -> Tells the name of script
# store first argument as username
USER_NAME="{$1}"
# All other arguments as comment
shift
COMMENT="{$@}"
# create a password
RANDOM_PASS=$(date +%s%N)
# seconds and nano seconds
# create a user
useradd -c "${COMMENT}" -m $USER_NAME
# -c -> comment
# -m -> Make Dir
# Check if user created successfully or not
if [[ $? -ne 0 ]]
then
echo "Failed to create user"
exit 1
fi
# set password for user
echo $PASSWORD | passwd --stdin $USER_NAME
# Check if password is successfully set or not
if [[ $? -ne 0 ]]
then
echo "Failed to create user"
exit 1
fi
# force password change on first login
passwd -e $USER_NAME
# Display username password and hostname
echo "Username: $USER_NAME"
echo "Username: $PASSWORD"
echo "Hostname: $(hostname)"
Top comments (0)