You can find this course on Learnshell.org
My GitHub Repo with exercices art-dambrine/learnshell @GitHub
1/ Hello, World! - Intro
To execute, simply write the shell script file name, once the file has execute permission (chmod +x filename).
Note
|
The first line of the shell script file begins with a "sha-bang" (#!) |
Adding comments
Any text following the "#" is considered a comment
Find out what is currently active shell
ps | grep $$
which bash
2/ Variables
Note
|
Shell variables are created once they are assigned a value. |
Name is case sensitive and can consist of a combination of letters and the underscore "_". Value assignment is done using the "=" sign. Note that no space permitted on either side of = sign.
Referencing the variables
A backslash "\" is used to escape special character meaning
PRICE_PER_APPLE=5
echo "The price of an Apple today is: \$HK $PRICE_PER_APPLE"
Encapsulating the variable name with ${} is used to avoid ambiguity
MyFirstLetters=ABC
echo "The first 10 letters in the alphabet are: ${MyFirstLetters}DEFGHIJ"
Variables can be assigned with the value of a command output. This is referred to as substitution. Substitution can be done by encapsulating the command with `` (known as back-ticks) or with $()
FILELIST=`ls`
FileWithTimeStamp=/tmp/my-dir/file_$(/bin/date +%Y-%m-%d).txt
3/ Passing arguments to the script
Inside the script, the $1
variable references the first argument in the command line.
The $0
variable references to the current script
The variable $#
holds the number of arguments passed to the script
echo $# --> results with: 6
Note
|
The variable $@ holds a space delimited string of all arguments passed to the script
|
4/ Arrays
To create an array in bash space-delimited values enclosed in ()
my_array=(apple banana "Fruit Basket" orange)
new_array[2]=apricot
The total number of elements in the array is referenced by ${#arrayname[@]}
my_array=(apple banana "Fruit Basket" orange)
echo ${#my_array[@]} # 4
The array elements can be accessed with their numeric index. The index of the first element is 0.
my_array=(apple banana "Fruit Basket" orange)
echo ${my_array[3]} # orange - note that curly brackets are needed
# adding another array element
my_array[4]="carrot" # value assignment without a $ and curly brackets
echo ${#my_array[@]} # 5
echo ${my_array[${#my_array[@]}-1]} # carrot
5/ Array comparison
# basic construct
# array=(value1 value2 ... valueN)
array=(23 45 34 1 2 3)
#To refer to a particular value (e.g. : to refer 3rd value)
echo ${array[2]}
#To refer to all the array values
echo ${array[@]}
#To evaluate the number of elements in an array
echo ${#array[@]}
6/ Basic Operators
Arithmetic Operators
Simple arithmetics on variables can be done using the arithmetic expression: $expression
A=3
B=$((100 * $A + 5)) # 305
Some operators you might not know
-
a % b
modulo (the integer remainder of a divided by b) -
a ** b
exponentiation (a to the power of b)
7/ Basic String Operations
The shell allows some common string operations which can be very useful for script writing.
String Length
# 1234567890123456
STRING="this is a string"
echo ${#STRING} # 16
Index
Find the numerical position in $STRING of any single character in $SUBSTRING that matches. Note that the 'expr' command is used in this case.
STRING="this is a string"
SUBSTRING="hat"
expr index "$STRING" "$SUBSTRING" # 1 is the position of the first 't' in $STRING
Substring Extraction
Extract substring of length $LEN from $STRING starting after position $POS. Note that first position is 0.
STRING="this is a string"
POS=1
LEN=3
echo ${STRING:$POS:$LEN} # his
Note
|
If :$LEN is omitted, extract substring from $POS to end of line
|
STRING="this is a string"
echo ${STRING:1} # $STRING contents without leading character
echo ${STRING:12} # ring
Simple data extraction example:
# Code to extract the First name from the data record
DATARECORD="last=Clifford,first=Johnny Boy,state=CA"
COMMA1=`expr index "$DATARECORD" ','` # 14 position of first comma
CHOP1FIELD=${DATARECORD:$COMMA1} #
COMMA2=`expr index "$CHOP1FIELD" ','`
# 6 is size of the word 'first=' and 1 is the size of a char comma
LENGTH=`expr $COMMA2 - 6 - 1`
FIRSTNAME=${CHOP1FIELD:6:$LENGTH} # Johnny Boy
echo $FIRSTNAME
Substring Replacement
Replace first occurrence of substring with replacement
STRING="to be or not to be"
echo ${STRING[@]/be/eat} # to eat or not to be
Replace all occurrences of substring
STRING="to be or not to be"
echo ${STRING[@]//be/eat} # to eat or not to eat
Delete all occurrences of substring (replace with empty string)
STRING="to be or not to be"
echo ${STRING[@]// not/} # to be or to be
Replace occurrence of substring if at the beginning of $STRING
STRING="to be or not to be"
echo ${STRING[@]/#to be/eat now} # eat now or not to be
Replace occurrence of substring if at the end of $STRING
STRING="to be or not to be"
echo ${STRING[@]/%be/eat} # to be or not to eat
Replace occurrence of substring with shell command output
STRING="to be or not to be"
echo ${STRING[@]/%be/be on $(date +%Y-%m-%d)} # to be or not to be on 2012-06-14
8/ Decision making
The shell also supports logical decision making.
if [ expression ]; then
code if 'expression' is true
fi
Shell syntax for decision making
NAME="George"
if [ "$NAME" = "John" ]; then
echo "John Lennon"
elif [ "$NAME" = "George" ]; then
echo "George Harrison"
else
echo "This leaves us with Paul and Ringo"
fi
Comparisons
Numeric
comparison Evaluated to true when
$a -lt $b $a < $b
$a -gt $b $a > $b
$a -le $b $a <= $b
$a -ge $b $a >= $b
$a -eq $b $a is equal to $b
$a -ne $b $a is not equal to $b
String
comparison Evaluated to true when
"$a" = "$b" $a is the same as $b
"$a" == "$b" $a is the same as $b
"$a" != "$b" $a is different from $b
-z "$a" $a is empty
Note
|
whitespace around = is required |
Note
|
use "" around string variables to avoid shell expansion of special characters as * |
Case structure
case "$variable" in
"$condition1" )
command...
;;
"$condition2" )
command...
;;
esac
Exemple for simple case
mycase=1 case $mycase in 1) echo "You selected bash";; 2) echo "You selected perl";; 3) echo "You selected phyton";; 4) echo "You selected c++";; 5) exit esac
9/ Loops
Bash for loop
Note
|
it’s a foreach |
# basic construct
for arg in [list]
do
command(s)...
done
For each pass through the loop, arg takes on the value of each successive value in the list. Then the command(s) are executed.
# loop on array member
NAMES=(Joe Jenny Sara Tony)
for N in ${NAMES[@]} ; do
echo "My name is $N"
done
# loop on command output results
for f in $( ls prog.sh /etc/localtime ) ; do
echo "File is: $f"
done
Bash while loop
# basic construct
while [ condition ]
do
command(s)...
done
The while construct tests for a condition, and if true, executes commands. It keeps looping as long as the condition is true.
COUNT=4
while [ $COUNT -gt 0 ]; do
echo "Value of count is: $COUNT"
COUNT=$(($COUNT - 1))
done
Bash until loop
# basic construct
until [ condition ]
do
command(s)...
done
The until construct tests for a condition, and if false, executes commands. It keeps looping as long as the condition is false (opposite of while construct)
COUNT=1
until [ $COUNT -gt 5 ]; do
echo "Value of count is: $COUNT"
COUNT=$(($COUNT + 1))
done
Break and continue statements
break
and continue
can be used to control the loop execution of for, while and until constructs. continue is used to skip the rest of a particular loop iteration, whereas break is used to skip the entire rest of loop. A few examples:
# Prints out 0,1,2,3,4
COUNT=0
while [ $COUNT -ge 0 ]; do
echo "Value of COUNT is: $COUNT"
COUNT=$((COUNT+1))
if [ $COUNT -ge 5 ] ; then
break
fi
done
# Prints out only odd numbers - 1,3,5,7,9
COUNT=0
while [ $COUNT -lt 10 ]; do
COUNT=$((COUNT+1))
# Check if COUNT is even
if [ $(($COUNT % 2)) = 0 ] ; then
continue
fi
echo $COUNT
done