Skip to content

Instantly share code, notes, and snippets.

@mklef121
Last active August 27, 2022 11:16
Show Gist options
  • Select an option

  • Save mklef121/8736ed2642357fa074eaa129b6ee2693 to your computer and use it in GitHub Desktop.

Select an option

Save mklef121/8736ed2642357fa074eaa129b6ee2693 to your computer and use it in GitHub Desktop.
I have put together in this gist, practicals and theories you need to know to become a shell Ninja. This is because Shell Scripting allows you to encapsulate common lists of commands in a file, automate processes and build easily configurable tools.

BASH SCRIPTING-- Bourne-Again Shell

A shell script is a computer program designed to be run by the Unix/Linux shell. A shell is a command-line interpreter and typical operations performed by shell scripts include file manipulation, program execution, and printing text.

Unix/Linux shells include

  • The Bourne Shell
    • Bourne shell (sh)
    • Korn shell (ksh)
    • Bourne Again shell (bash)
    • POSIX shell (sh)
  • The C Shell

Shell scripts and functions are both interpreted. This means they are not compiled.

Example Script
  • #!/bin/sh: It is called a called a shebang because the # symbol is called a hash, and the ! symbol is called a bang. This tells the system that the commands that follow are to be executed by the Bourne shell.
  • # : Starts a comment
  • chmod +x script_name.sh : give executable permission of the script to the current user.
#!/bin/sh \

# Author : Zara Ali \
# Copyright (c) Tutorialspoint.com \
# Script follows here: \

echo "What is your name?" \
read PERSON \
echo "Hello, $PERSON" \

Defining Variables

Variables follow the same convention as normal programming languages.

variable_name=variable_value

For example −

NAME="Zara Ali"
VAR1="Zara Ali"
VAR2=100

Accessing Variable.

Prefix its variable names with the dollar sign ($) to access them.

#!/bin/sh

NAME="Zara Ali"
echo $NAME
Read-only Variables

After a variable is marked read-only, its value cannot be changed.

#!/bin/sh

NAME="Zara Ali"
readonly NAME
NAME="Qadiri"
Unsetting Variables

Unsetting or deleting a variable directs the shell to remove the variable from the list of variables that it tracks.

unset variable_name

Types of Variables

  1. Local Variables: A local variable is a variable that is present within the current instance of the shell.
  2. Environment Variables: An environment variable is available to any child process of the shell. Some programs need environment variables in order to function correctly.
  3. Shell Variables: A shell variable is a special variable that is set by the shell and is required by the shell in order to function correctly.
Special Variables

I will discuss names of special Unix variables. These variables are reserved for specific functions.

  • $$: represents the process ID number, or PID, of the current shell. E.G: echo $$ -- will output a number like 7475
  • $0: The filename of the current script. E.G echo $0 might output /bin/bash
  • $n: here n is a positive integer corresponding to the position of an argument --> These variables correspond to the arguments with which a script was invoked. E.G /bin/bash ./test.sh van name she inside the ./test.sh script $1 = van, $2 = name, $3 = she
  • $#: The number of arguments supplied to the script. From the above example $# = 3
  • $? : The exit status of the last command executed.
  • $* : This takes all input argument and converts them a single string or itterable list. E.G /bin/bash ./test.sh van name she => echo $* will result in "van name she". Better still
#!/bin/sh

for TOKEN in $*
do
   echo $TOKEN
done
  • $! : The process number of the last background command.

Exit status is a numerical value returned by every command upon its completion. As a rule, most commands return an exit status of 0 if they were successful, and 1 if they were unsuccessful.

Shell Arrays

To set arrays in bash, use the syntax array_name=(value1 value2 ... valuen) or doing this array_name[index] = value

array_name=(hello come Go 45)
allThreads=(1 2 4 8 16 32 64 128)

#accessing values
first=${array_name[index]}

#Accessing all values in array 

${array_name[*]}
${array_name[@]}

${!allThreads[@]} -- returns list of all array indexes

# appending values to array
array_name +=(new_item)

#Looping through array elements

for item in ${allThreads[@]}; do
  echo $item
done

# Using the array index list

for index in ${!allThreads[@]}; do
  echo ${array_name[index]}
done

allRuntimes=() #Initialise empty array

Basic Operators

Arithmetic Operators are run using the exp helper E.G

val = `expr 2 + 2`. #take note of the backticks

a=10
b=20
`expr $a + $b` #will give 30 - Addition
`expr $a - $b` # will give -10 - Subtraction
`expr $a \* $b` #will give 200 - multiplication
`expr $b / $a` #will give 2 - Division
`expr $b % $a` #will give 0 - modulus
 a = $b # would assign value of b into a -- Assignment
[ $a == $b ] #would return false. -- Equality
[ $a != $b ] would return true. -- Not Equality

The Following rules will guide these expressions

  • There must be spaces between operators and expressions. For example, 2+2 is not correct; it should be written as 2 + 2.
  • The complete expression should be enclosed between ‘ ‘, called the backtick.
  • all the conditional expressions should be inside square braces with spaces around them, for example [ $a == $b ] is correct whereas, [$a==$b] is incorrect.

Relational Operators

The following relational operators are specific to numeric values, They do not work on string values.

a=10
b=20
[ $a -eq $b ] is not true. -- Equal to
[ $a -ne $b ] is true. -- Not Equal
[ $a -gt $b ] is not true. -- Greater Than
[ $a -lt $b ] is true. -- Less Than
[ $a -ge $b ] is not true. -- Greater than or Equal to
[ $a -le $b ] is true. -- Less than or equal to

String Operators

a="abc"
b="efg"

[ $a = $b ] is not true. //Checks if the value of two operands are equal or not
[ $a ] is not false. // Checks if string is empty

Most times its better to do comparison using double brackets Thus if [[ $var = $var1 ]]; then for string comparison or if [ "$var" == "$var1" ]; then to escape 'unary operator expected' error. See Stack Overflow and Linux Command

File Test Operators

file="~./Documents/test.sh"

Command Operator Description
-d [ -d $file ] is not true. Checks if file is a directory
-b [ -b $file ] is false. Checks if file is a block special file;
-f [ -f $file ] is true. Checks if file is an ordinary file as opposed to a directory or special file.
-p [ -p $file ] is false. Checks if file is a named pipe.
-r [ -f $file ] is true. Checks if file is readable.
-w [ -f $file ] is true. Checks if file is writable.
-x [ -f $file ] is true. Checks if file is executable.
-s [ -f $file ] is true. Checks if file has size greater than 0.
-e [ -f $file ] is true. Checks if file exists.

Conditional Statement

Unix Shell supports following forms of if…else statement −

  • if... fi statement
  • if... else... fi statement
  • if... elif... else... fi statement
  1. if... fi statement : fundamental control statement that allows Shell to make decisions and execute statements conditionally.
 #!/bin/sh

a=10
b=20

if [ $a == $b ]
then
   echo "a is equal to b"
fi
  1. if... else... fi statement : Examples below.
#!/bin/sh

a=10
b=20

if [ $a == $b ]
then
   echo "a is equal to b"
else
   echo "a is not equal to b"
fi
  1. if... elif... else... fi statement : Examples below.
#!/bin/sh

a=10
b=20

if [ $a == $b ]
then
   echo "a is equal to b"
elif [ $a -gt $b ]
then
   echo "a is greater than b"
elif [ $a -lt $b ]
then
   echo "a is less than b"
else
   echo "None of the condition met"
fi

Shell Loops

we will examine the following types of loops available to shell programmers −

  • The while loop
  • The for loop
  • The until loop
  • The select loop
  1. The while loop: See example below
#!/bin/sh

a=0

while [ $a -lt 10 ]
do
   echo $a
   a=`expr $a + 1`
done
  1. The for loop: See example below
#!/bin/sh
#uses the for loop to span through the given list of numbers 

for var in 0 1 2 3 4 5 6 7 8 9
do
   echo $var
done

#display all the files starting with .bash and available in your home
for FILE in $HOME/.bash*
do
   echo $FILE
done
  1. Until loops: Used to execute a set of commands until a condition is true.
 #!/bin/sh

a=0
#execute until $a is no longer less than 10
until [ ! $a -lt 10 ]
do
   echo $a
   a=`expr $a + 1`
done
  1. Select loop -- Look am later

Shell Loop Control

Use the break and continue statement to control loop in shell

#!/bin/sh

a=0

while [ $a -lt 10 ]
do
   echo $a
   if [ $a -eq 5 ]
   then
      break #breaks out of single while loop
   fi
   a=`expr $a + 1`
done


for var1 in 1 2 3
do
   for var2 in 0 5
   do
      if [ $var1 -eq 2 ] && [ $var2 -eq 0 ]
      then
         break 2 # we told the break here to break out of double loops
      else
         echo "$var1 $var2"
      fi
   done
done


NUMS="1 2 3 4 5 6 7"

for NUM in $NUMS
do
   Q=`expr $NUM % 2`
   if [ $Q -eq 0 ]
   then
      echo "Number is an even number!!"
      continue  #The continue statement
   fi
   echo "Found odd number"
done

Shell Substitution

The shell performs substitution when it encounters an expression that contains one or more special characters.

#!/bin/sh

a=10
echo  "Value of a is $a \n"

# variable a is substituted by its value, also "\n" is substituted by a new line

Special characters include \r, \\, \n e.t.c

####### Command Substitution

The command substitution is performed when a command is given as −

#!/bin/sh

DATE=`date` #variable DATE now has the value of todays date.
echo "Date is $DATE" 

USERS=`who | wc -l`
echo "Logged in user are $USERS"

UP=`date ; uptime`
echo "Uptime is $UP"
Variable Substitution
  • ${var} : Substitute the value of var.
  • ${var:-word} : If var is null or unset, word is substituted for var. E.G
#!/bin/bash
 echo ${mimiVar:-"They did not set me"}
# this displays "They did not set me"

mimiVar="Set up mimi variable"
echo ${mimiVar:-"They did not set me"}
# Displays "Set up mimi variable"
  • ${var:=word}: If var is null or unset, var is set to the value of word.
  • ${var:?message} : If var is null or unset, message is printed to standard error. This checks that variables are set correctly.
  • ${var:+word} : If var is set, word is substituted for var. The value of var does not change.
Escaping special Characters

* ? [ ] ' " \ $ ; & ( ) | ^ < > All these are special characters to escape the, use \ or ' '

Its good to note that the single quote ' prevents variable substitution meaning

VAR=ZARA
echo '$VAR owes <-$1500.**>; [ as of (`date +%m/%d`) ]'` 

#will output

$VAR owes <-$1500.**>; [ as of (`date +%m/%d`) ]

#To fix this, use double quotes " "
echo "$VAR owes <-\$1500.**>; [ as of (`date +%m/%d`) ]"
Shell Input/Output Redirections

Most Unix system commands take input from your terminal and send the resulting output back to your terminal. A command normally reads its input from the standard input, which happens to be your terminal by default. Similarly, a command normally writes its output to standard output, which is again your terminal by default.

Output Redirection

The output from a command normally intended for standard output can be easily diverted to a file instead.

who > users.txt

This command above will redirect the output of who into users.txt file. The output has been redirected from the default standard output device (the terminal) into the specified file.

You can use >> operator to append the output in an existing file as follows −

echo line 1 > users
echo line 2 >> users
cat user
 > line 1
 > line 2
Input Redirection

The less-than character < is used to redirect the input of a command.

wc -l < users

The WC command is used for counting words, lines, character and bytes of a file or standard input. Look up here

####Here Document A here document is used to redirect input into an interactive shell script or program.

It takes the following format

command << delimiter
	document
delimiter

Here the shell interprets the << operator as an instruction to read input until it finds a line containing the specified delimiter.

wc -l << EOF
   This is a simple lookup program 
	for good (and bad) restaurants
	in Cape Town.
EOF

#displays
3
Discard the output

You can discard the output by redirecting it to the file /dev/null this is a special file that automatically discards all its input.

command > /dev/null

This does not mean that if an error occurs, it would not be shown on the terminal.

To discard both output of a command and its error output, use standard redirection to redirect STDERR to STDOUT

Remember that UNIX considers everything, even a printer or your mouse, a file.

command > /dev/null 2>&1

Here 2 represents STDERR and 1 represents STDOUT.

You can even redirect STDOUT to STDERR; This means a success will still throw an error.

echo message 1>&2

./test.sh 1>&/dev/null   #redirects standard output to null file

UNIX uses file descriptors, which are positive integer values, as an internal representation for accessing all of its open files, which is much prettier than using long paths. So, by default, all UNIX systems support three special and standard filenames: /dev/stdin, /dev/stdout, and /dev/stderr, which can also be accessed using file descriptors 0, 1, and 2, respectively.

Shell Functions

Functions enable you to break down the overall functionality of a script into smaller, logical subsections, which can then be called upon to perform their individual tasks when needed.

function_name () { 
  list of commands
}
#!/bin/sh

# Define your function here
Hello () {
   echo "Hello World"
}

# Invoke your function
Hello
Pass Parameters to a Function
#!/bin/sh

# Define your function here
Hello () {
   echo "Hello World $1 $2"
}

# Invoke your function
Hello Zara Ali

These parameters would be represented by $1, $2, $...n and so on.

Returning Values from Functions

The syntax below must be inside the function

return code

Example:

#!/bin/sh

# Define your function here
Hello () {
   echo "Hello World $1 $2"
   return 10
}

# Invoke your function
Hello Zara Ali

# Capture value returnd by last command
ret=$?

echo "Return value is $ret"

# Return value is 10

One of the more interesting features of functions is that they can call themselves(recursion) and also other functions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment