Level Up Your Shell Scripting

Summarizing what I learned about shell scripting. So what is Shell and Shell Scripting ?

Pinky Gautam
7 min readDec 17, 2023
Photo by Gabriel Heinzer on Unsplash

Summarizing what I learned about shell scripting. So what is Shell and Shell Scripting ? Shell is an interface between user and operating system (OS). Shell Scripting is simply writing a sequence of Shell commands to files in order to automate processes in Linux OS

Operating System is a software that manages hardwares and provide services to other softwares

Basic Linux Commands

# FOR EXAMPLE ONLY

pwd # prints current directory
which program # find program file in path variable
ls dir_name # list directory content
touch file_name # creates a new file
mkdir dir_name # creates a new directory
cd target_dir # change directory to target_dir
mv source target # move file or directory from source to target

cp source target # copy file from source to target
cp -r source target # copy directory from source to target

rm target # remove target file
rm -r target # remove target directory

cat file1 file2 # read and concatenate file contents
grep pattern file # search for text in file
man command # print command manual
sleep seconds # wait for specified seconds

Access Management Commands

# FOR EXAMPLE ONLY

# modes comprise of permission for owner, owner group, others
# 0 = no permission
# 1 = execute/search permission
# 2 = write permission
# 4 = read permission
chmod 700 file # grant file owner to read, write and execute the file
chmod -R 660 dir # grant read and write on directory to owner and group members
chmod 444 file # grant everyone to read file


chown new_owner file # change file owner
chown :new_group file # change file group
chown new_owner:new_group file # change file owner and group

chown -R new_owner dir # change folder owner
chown -R :new_group dir # change folder group
chown -R new_owner:new_group dir # change folder owner and group

Following commands are useful for passing program output to file, stream or another program

# FOR EXAMPLE ONLY

# pipe | passes output as input to another program
echo "piping the pipe" | grep "pipe"

# redirect > passes output to either a file or stream
echo 1234 > file.txt # overwrites file.txt
echo 1234 >> file.txt # appends to file.txt

Shebang

We can specify type of shell for script execution through shebang. shebang includes #! and the absolute path to the desired shell interpreter. Note that shebang must be placed at the first line of script

Following is shebang telling to use Bourne shell (sh) for script execution

#! /bin/sh

Script Execution

Given that a script named comparison.sh is present in numeric sub-folder of comparison folder inside current directory, the script is run as follows

Variables

Variables need to be defined first in order to be referred later

#! /bin/sh

# variable definition
greeting="Hello"
name="Linux"

echo $greeting $name # variable reference

Arithmetic Expressions

Following table shows syntax of arithmetic operators and their meaning

Evaluate arithmetic expression and optionally store the result in a variable. Use bash calculator to perform calculations related to decimal numbers as decimal numbers are treated as strings by default

#! /bin/sh

exp_result=$((2*4)) # arithmetic expression
echo $exp_result

echo "scale=2;18.22/4" | bc # truncate decimal to 2 places

Input Output

Get input from user through console and output (print) the value received

#! /bin/sh

# get input from console and store in person_name variable
read -p "Enter your name : " person_name

# convert string to upper case
person_name=$(echo $person_name | tr 'a-z' 'A-Z')
echo "Hello $person_name" # output (print) value to console

Conditional Statements

Parts of conditional statement are if, elif and else clauses where elif and else clauses are optional

if ... then ... elif … then ... else … fi

Conditional statements can also be nested

if … then … else if … then … fi fi

String Comparison

Following table shows syntax of comparison operators and their meaning

Compare string lexicographically

#! /bin/sh

if [[ "bc" < "bcc" ]] # lexicographical comparison
then
echo "bc comes before bcc in dictionary"
fi

Finding Substring

Check if string contains specified substring

#! /bin/sh

# check for substring awesome
if echo "It's awesome" | grep -q "awesome" # -q = quiet
then
echo "contains awesome"
fi

Extracting Pattern

Extract part of string that matches with specified pattern, if string contains the pattern

#! /bin/sh

ph="ph: 091-123-9878."
re="(0[0-9]{2}\-[0-9]{3}\-[0-9]{4})"

if [[ "$ph" =~ $re ]]; then
# extract matched part
echo $ph | grep -Eo $re # -E = allow regex, -o output matched parts
fi

Integer Comparison

Following table shows syntax of comparison operators and their meaning

Number Comparison

Conditional statement for decimal safe number comparison

#! /bin/sh

read -p "Enter first number : " num1
read -p "Enter second number : " num2

# safe comparison even for decimal numbers
if [[ $(echo "${num1} == ${num2}" | bc) -eq 1 ]]
then
echo 'numbers are equal'
else
if [[ $(echo "${num1} > ${num2}" | bc) -eq 1 ]]
then
echo 'first number > second number'
else
echo 'first number < second number'
fi
fi

Logical Operation

Following table represents syntax of logical operators and their meaning

Conditional statement (boolean comparison) using logical operations

#! /bin/sh

cond1=false
cond2=false
if [[ "$cond1" == true && "$cond2" == true ]]
then
echo 'and matched'
elif [[ "$cond1" == true || "$cond2" == true ]]
then
echo 'or matched' # if condition not matched
else
# no outer conditions matched
if ! [[ "$cond2" == true ]]
then
echo 'cond2 false'
# do nothing when condition not matched
fi
fi

For Loop

Loop through elements in a list

#! /bin/sh

# for loop with list of strings
for fruit in apple banana "dragon fruit"
do
echo $fruit
done

List elements that meet specific condition(s) can be skipped with continue keyword

#! /bin/sh

# for loop with numbers
for i in {1..5} # generate list of numbers from 1 to 5
do
if [[ $(echo "${i} % 4 == 0" | bc) -eq 0 ]]
then
continue # skip remaning lines and continue looping
fi
echo $i
done

While Loop

Loop until loop condition is not met. Loops can also be exited in the middle with break keyword

#! /bin/sh

i=1
while [[ true == true ]]
do
if [[ $i -gt 2 ]]
then
break
fi
echo $i
i=$(($i + 1))
done

Read File

Suppose we have a file called sample_file.txt in file directory, we can read the file line by line and print the output as follows

#! /bin/sh

line=1

# read file line by line
while read -r current_line # -r = not discard (escape) backslash
do
echo "line $line: $current_line"
line=$(($line+ 1))
done < "file/sample_file.txt"

Backticks

Wrap a command with backticks to include output of the command in a shell script

#! /bin/sh

str='invoice no. 123009287A'
match=`echo $str | grep -Eo '[0-9]{9,}[A-Z]'`
echo 'extracted invoice number is' $match

Script Arguments

#! /bin/sh

for arg in $@ # $@ = list of script arguments
do
echo "Entered argument is" $arg
done

The script above loops through all of its arguments. Given that script above is named as args.sh and is placed in current directory, passing argument to the script is done as follows

Nth argument of a script is accessed as follows

#! /bin/sh

echo "first argument:" $1
echo "third argument:" $3

Shell scripting comes with plenty of useful commands satisfying different use cases. Shell Scripting enhance reusability of commands by recording them into files for re-execution in future. Shell Scripting is a powerful utility for repeatedly automating the same task

References

--

--