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.
#!/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 commentchmod +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" \Variables follow the same convention as normal programming languages.
variable_name=variable_value
For example −
NAME="Zara Ali"
VAR1="Zara Ali"
VAR2=100Accessing Variable.
Prefix its variable names with the dollar sign ($) to access them.
#!/bin/sh
NAME="Zara Ali"
echo $NAMEAfter a variable is marked read-only, its value cannot be changed.
#!/bin/sh
NAME="Zara Ali"
readonly NAME
NAME="Qadiri"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
- Local Variables: A local variable is a variable that is present within the current instance of the shell.
- Environment Variables: An environment variable is available to any child process of the shell. Some programs need environment variables in order to function correctly.
- 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.
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.Gecho $0might output/bin/bash$n: herenis 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 sheinside 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.
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 arrayArithmetic 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.
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
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="~./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. |
Unix Shell supports following forms of if…else statement −
- if... fi statement
- if... else... fi statement
- if... elif... else... fi statement
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"
fiif... 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
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"
fiwe will examine the following types of loops available to shell programmers −
- The while loop
- The for loop
- The until loop
- The select loop
- The while loop: See example below
#!/bin/sh
a=0
while [ $a -lt 10 ]
do
echo $a
a=`expr $a + 1`
done- 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
- 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- Select loop -- Look am later
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"
doneThe 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 lineSpecial 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"${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.
* ? [ ] ' " \ $ ; & ( ) | ^ < > 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`) ]"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.
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
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
3You 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.
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#!/bin/sh
# Define your function here
Hello () {
echo "Hello World $1 $2"
}
# Invoke your function
Hello Zara AliThese parameters would be represented by $1,
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 10One of the more interesting features of functions is that they can call themselves(recursion) and also other functions.