Follows the course on https://www.youtube.com/watch?v=e7BufAVwDiM&t=10058s Start your bash script with
#! /bin/bash
To show your shell environments use
cat /etc/shells
Bash scripts end in .sh. To make a script executeable, do the following
chmod +x <filename>
Use >
to put echo contents into file
echo "hello bash script" > 02_file.txt
cat > 02_file.txt
Use >>
to append.
echo "this is some content after" >> 02_file.txt
Use : '<your comment here>'
for multiline comments.
Use the following structure if []/(())
then
, else
, elif []/(())
, fi
#! /bin/bash
count=8
if (( $count < 9)) && (( $count >= 0 ))
then
echo "count is between 9 and 0"
elif (($count == 10))
then
echo "the condition is true"
else
echo "the condition is false"
fi
While loop
#! /bin/bash
number=1
while (( $number < 10 ))
do
echo "$number"
number=$(( number+1 ))
done
For loop
for i in 1 2 3 4 5
do
echo $i
done
or using a range. Note! it includes the end {start..end..increment} We can also use C-style for loops (( i=0; i<5; i++ ))
for i in {0..20..2}
do
echo $i
done
We can also use break
or continue
controls
Use the $
to get the args. Note $0 is the filename
#! /bin/bash
echo $0 $1 $2 $3
# Also we can get all the args as an array
args=("$@")
# Print out the all of the arguments
echo $@
# Length of the array
echo $#
Reading a file
#! /bin/bash
while read line
do
echo "$line"
done < "${1:-/dev/stdin}"
# ${1....} Means to take the first argument
Use 1>
for STDOUT and 2>
for STDERR. Use >&
for both.
#! /bin/bash
ls -a 1>07_output.txt 2>07_err_log.txt
Tranferring stuff from one script to another. We can use export to send variables to another script.
08_firstScript.sh
#! /bin/bash
MESSAGE="Hello world"
export MESSAGE
./08_secondScript.sh
08_secondScript.sh
echo "This is the message from secondScript: $MESSAGE"
Comparing
#! /bin/bash
echo "enter 1st string"
read st1
echo "enter 2st string"
read st2
if [ "$st1" == "$st2" ]
then
echo "Strings are the same"
else
echo "Strings are different"
fi
if [ "$st1" \< "$st2" ]
then
echo "string 2 is larger"
else
echo "String 1 is larger"
fi
# Concatenation
c="$st1 $st2"
echo "Concatenation $c"
# Lower case and Upper case
echo ${st1,,}
echo ${st2^^}
# Upper case first letter.
echo ${st1^l}
We need to use $(())
to do math. By default, operations will be performed
on ints. We can also use $(expr <your expression>)
.
#! /bin/bash
n1=4
n2=20
echo $(( n1 + n2 ))
echo $(( n1 - n2 ))
echo $(( n1 * n2 ))
echo $(( n1 / n2 ))
echo $(( n1 % n2 ))
echo $(expr $n1 + $n2 )
echo $(expr $n1 - $n2 )
echo $(expr $n1 \* $n2 )
echo $(expr $n1 / $n2 )
echo $(expr $n1 % $n2 )
#! /bin/bash
echo "Enter Hex Number of you choice"
read Hex
echo -n "The decimal value of $Hex is : "
echo "obase=10; ibase=16; $Hex" | bc
Using declare is very similar to using const, let, var
#! /bin/bash
declare -r pwdfile=/etc/passwd
echo $pwdfile
# Try changing a read-only file
pwdfile=/etc/abc.txt
echo $pwdfile
Working with arrays.
#! /bin/bash
car=('BMW' 'Toyota' 'Honda')
echo "${car[@]}"
# The 0-th index of the array
echo "${car[0]}"
# Show the index
echo "${!car[@]}"
# The length of the array
echo "${#car[@]}"
# Deleting elements in the array
unset car[2]
echo "${car[@]}"
# Insert element
car[2]='Lambo'
echo "${car[@]}"
Note that bash functions cannot return a value. What needs to be done is to set a global variable and read from it. All variables are global by default in bash.
#! /bin/bash
function funcName() {
echo "this is new functions"
}
# Adding arguments (same with getting arguments from CLI)
# Also assigning global variables.
function funcPrint() {
isDone="i am done"
echo "Printing from inside function: $1"
}
# Call the functions
funcName
funcPrint "Hi World"
echo "funcPrint : $isDone"
Use -d
to check if dir exists. Use -f
to check if file exists.
#! /bin/bash
# Check if a directory exists
echo "Enter directory name to check"
read direct
if [ -d "$direct" ]
then
echo "$direct exists already"
else
echo "$direct doesn't exist"
fi
# Create a file
echo "Enter the file name to create"
read fileName
# Check if file exists
if [ -f "$fileName" ]
then
echo "$direct exists"
else
echo "$direct doesn't exist"
touch $fileName
fi
We need to use ssmtp
sudo apt install ssmtp
Create a ssmtp.conf file with the following parameters
ssmtp.conf
[email protected]
mailhub=smtp.gmail.com:587
[email protected]
AuthPass=securepass
UseSTARTTLS=yes
Downloading stuff.
When using curl, use the -O
option to inherit the filename.
We can change the filename by using the -o <filename>
Look at the file header by using th -I
flag.
#! /bin/bash
url="http://speedtest.ftp.otenet.gr/files/test100k.db"
curl -I ${url}
curl ${url} -O
curl ${url} -o 16_test100k.db
Use select <varname> in <space separatedlist>
.
#! /bin/bash
select car in BMW MERCEDESE TESLA ROVER TOYOTA
do
case $car in
BMW)
echo "BMW SELECTED";;
MERCEDESE)
echo "MERCEDESE SELECTED";;
TESLA)
echo "TESLA SELECTED";;
ROVER)
echo "ROVER SELECTED";;
TOYOTA)
echo "TOYOTA SELECTED";;
*)
echo "ERROR PLEASE SELECT THE CORRECT ONE";;
esac
done
To use inotify, we need to install inotify-tools. When stuff happens inside the directory then we will be notified what happens.
sudo apt install inotify-tools
Do not open log.txt while inotifywait is running or else there will be some sort of infinite loop.
#! /bin/bash
dirpath=./18_inotifydir
if [ ! -d dirpath ]
then
mkdir "$dirpath"
fi
inotifywait -m "$dirpath" >> "$dirpath/log.txt"
You need to escape most of the characters \+
, \?
, \{<num>\}
Use -n
to print out the line numbers
#! /bin/bash
echo "input filename: "
read filename
if [ -f $filename ]
then
# Get the emails
echo "----------------------------------------"
echo "All of the emails"
grep -n "^[a-zA-Z0-9]\+@[a-zA-Z0-9]\+.\(com\|ca\|co.jp\)" "$filename"
echo "----------------------------------------"
# All of the phone numbers
echo "All of the phone numbers"
grep "(\?[0-9]\{3\})\?-\?[0-9]\{3\}-\?[0-9]\{4\}" "$filename"
else
echo "Error: File does not exist"
fi
Use
bash -x ./<executable file>
In the script, you can also set -x
on the line to start debugging and
set +x
on the line to stop debugging.