OS Lab Lecture 2 - Shell Script-3
OS Lab Lecture 2 - Shell Script-3
Shell S c r i p t i n g
Fall 2024
Azizur Rahman Anik, Lecturer, UIU
2
W h a t i s Shell S c r i p t i n g ?
We've seen how to execute commands in the shell and pipe multiple
commands together.
Sometimes, we want to run many, many commands together and/or make
use of control flow expressions such as conditionals and loops.
3
W h a t i s Shell S c r i p t i n g ?
4
W h a t i s Shell S c r i p t i n g ?
Most shells have their own scripting language, each with its own
variables, control flow, and syntax.
What makes shell scripting different from other scripting languages is
that it is optimized for performing shell-related tasks.
Creating command pipelines, saving results into files, and reading from
standard input are baked into in shell scripting, making it easier to use
compared to other scripting languages.
5
Basics of Bash Scripting
Bash scripting refers to writing a script for a bash shell (Bourne Again
SHell).
6
Basics of Bash Scripting
Bash scripting refers to writing a script for a bash shell (Bourne Again
SHell).
7
Basics of Bash Scripting
Bash scripting refers to writing a script for a bash shell (Bourne Again
SHell).
8
Your V e r y F i r s t S c r i p t
9
Your V e r y F i r s t S c r i p t
#!/usr/bin/env bash
10
Your V e r y F i r s t S c r i p t
#!/usr/bin/env bash
11
Sheb a n g
The shebang, also called a sharp exclamation, is the very first line of a
script.
It is the combination of the pound symbol (#) and an exclamation mark
(!).
The shebang is used to specify the interpreter that the given script will
be run with. In our case, we indicate that we want a bash interpreter (i.e.
a bash shell). If you want to run your script with a zsh shell, you simply
change the shebang.
12
Sheb a n g
13
Running (Your V e r y F i r s t S c r i p t )
You can always run a shell script by simply prepending it with a shell
interpreter program:
14
Running (Your V e r y F i r s t S c r i p t )
You can always run a shell script by simply prepending it with a shell
interpreter program:
Interpreter
15
Running (Your V e r y F i r s t S c r i p t )
You can also run a script by turning it into an executable program and
then running it.
16
Running (Your V e r y F i r s t S c r i p t )
You can also run a script by turning it into an executable program and
then running it.
First, turn the program into an executable using chmod (change mode):
chmod +x [Link]
17
Running (Your V e r y F i r s t S c r i p t )
You can also run a script by turning it into an executable program and
then running it.
First, turn the program into an executable using chmod (change mode):
chmod +x [Link]
18
Running (Your V e r y F i r s t S c r i p t )
You can also run a script by turning it into an executable program and
then running it.
First, turn the program into an executable using chmod (change mode):
chmod +x [Link]
19
Bash Scripting: Variables
20
Bash Scripting: Variables
21
Bash Scripting: Variables
22
Bash Scripting: Strings
23
Bash Scripting: Strings
24
Bash Scripting: Strings
x=foo x=foo
echo '$x' echo "$x"
# prints $x # prints foo
25
Your V e r y F i r s t S c r i p t
#!/usr/bin/env bash
greeting="Hello world!"
echo $greeting
26
Bash Scripting: Control Flow
Like other programming languages, bash scripts also have control flow
directives such as if, for, while, and case.
27
Bash Scripting: Control Flow
Like other programming languages, bash scripts also have control flow
directives such as if, for, while, and case.
#!/usr/bin/env bash
if [ CONDITION ]
then
# do something
fi
28
Bash Scripting: Control Flow
Like other programming languages, bash scripts also have control flow
directives such as if, for, while, and case.
#!/usr/bin/env bash
lt (less than)
num=101 le (less than or equal to)
if [ $num -gt 100 ] eq (equal to)
ge (greater than or equal to)
then gt (greater than)
echo "That's a big number!" ne (not equal to)
fi
29
Bash Scripting: Control Flow
Like other programming languages, bash scripts also have control flow
directives such as if, for, while, and case.
#!/usr/bin/env bash
num=101
if [ $num -gt 100 ] && [ $num -lt 1000 ]
then
echo "That's a big (but not a too big) number!"
fi
30
Bash Scripting: Control Flow
#!/usr/bin/env bash
if [ CONDITION ]
then
# do something
elif [ CONDITION ]
then
# do something else
else
# do something totally different
fi
31
Bash Scripting: Control Flow
#!/usr/bin/env bash
num=101
if [ $num -gt 1000 ]
then
echo "That's a huge number!"
elif [ $num -gt 100 ]
then
echo "That's a big number!"
else
echo "That's a small number."
fi
32
If‐Else
Bash Scripting: Control Flow
Like other programming languages, bash scripts also have control flow
directives such as if, for, while, and case.
#!/usr/bin/env bash
while [ CONDITION ]
do
# do something
done
34
Bash Scripting: Control Flow
Like other programming languages, bash scripts also have control flow
directives such as if, for, while, and case.
#!/usr/bin/env bash
num=0
while [ $num -lt 100 ]
do
echo $num
num=$((num+1))
done
35
Bash Scripting: Control Flow
Like other programming languages, bash scripts also have control flow
directives such as if, for, while, and case.
#!/usr/bin/env bash
36
Bash Scripting: Control Flow
Like other programming languages, bash scripts also have control flow
directives such as if, for, while, and case.
#!/usr/bin/env bash
num=0
for i in {1..100}
do
echo $num
num=$((num+1))
done
37
Bash Scripting: Exercise
38
Bash Scripting: Exercise
#!/usr/bin/env bash
for i in {1..20}
do
echo $i
if [ $i -gt 10 ]
then
echo "I'm big!"
fi
done
39
Bash Scripting: Arguments
Let's take a look at how we might use command line arguments to make
our big_num.sh script a little more interesting.
40
Bash Scripting: Arguments
Let's take a look at how we might use command line arguments to make
our big_num.sh script a little more interesting.
In bash, the variables $1 - $9 refers to the arguments to a script.
41
Bash Scripting: Arguments
Let's take a look at how we might use command line arguments to make
our big_num.sh script a little more interesting.
In bash, the variables $1 - $9 refers to the arguments to a script.
42
Bash Scripting: Arguments
Let's take a look at how we might use command line arguments to make
our big_num.sh script a little more interesting.
In bash, the variables $1 - $9 refers to the arguments to a script.
This is $1
43
Bash Scripting: Arguments
Let's take a look at how we might use command line arguments to make
our big_num.sh script a little more interesting.
In bash, the variables $1 - $9 refers to the arguments to a script.
The variable $0 refers to the name of the script.
This is $1
44
Bash Scripting: Arguments
Let's take a look at how we might use command line arguments to make
our big_num.sh script a little more interesting.
In bash, the variables $1 - $9 refers to the arguments to a script.
The variable $0 refers to the name of the script.
This is $0 This is $1
45
Bash Scripting: Arguments
Let's assign num to be the first argument when calling the script.
adrazen@ayelet-computer ~ % sh big_num.sh 102
46
Bash Scripting: Arguments
Let's assign num to be the first argument when calling the script.
adrazen@ayelet-computer ~ % sh big_num.sh 102
This is $1
47
Bash Scripting: Arguments
Let's assign num to be the first argument when calling the script.
adrazen@ayelet-computer ~ % sh big_num.sh 102
#!/usr/bin/env bash
num=101
if [ $num -gt 100 ]
then
echo "That's a big number!"
fi
48
Bash Scripting: Arguments
Let's assign num to be the first argument when calling the script.
adrazen@ayelet-computer ~ % sh big_num.sh 102
#!/usr/bin/env bash
num=$1
if [ $num -gt 100 ]
then
echo "That's a big number!"
fi
49
Bash Scripting: Functions
50
Bash Scripting: Functions
#!/usr/bin/env bash
make_and_enter() {
# calls mkdir (including parent directories)
# calls cd
}
51
Bash Scripting: Functions
#!/usr/bin/env bash
make_and_enter(directory_name) {
mkdir -p directory_name
cd directory_name
}
52
Bash Scripting: Functions
#!/usr/bin/env bash
make_and_enter(directory_name) {
mkdir -p directory_name
cd directory_name
}
53
Bash Scripting: Functions
#!/usr/bin/env bash
make_and_enter() {
mkdir -p "$1"
cd "$1"
}
54
Bash Scripting: Functions
#!/usr/bin/env bash
make_and_enter() {
mkdir -p "$1"
cd "$1"
}
make_and_enter new_folder
55
Bash Scripting: Functions
#!/usr/bin/env bash
make_and_enter() {
mkdir -p "$1"
cd "$1"
}
make_and_enter new_folder
56
Bash Scripting: Functions
#!/usr/bin/env bash
make_and_enter() {
mkdir -p "$1"
cd "$1"
}
make_and_enter new_folder
57
Bash Scripting: Functions
#!/usr/bin/env bash
make_and_enter() {
mkdir -p "$1"
cd "$1"
}
make_and_enter new_folder
58
Bash Scripting: Functions
#!/usr/bin/env bash
make_and_enter() {
mkdir -p "$1"
cd "$1"
}
make_and_enter new_folder
59
Bash Scripting: Functions
#!/usr/bin/env bash
make_and_enter() {
mkdir -p "$1"
cd "$1"
}
make_and_enter new_folder
60
Bash Scripting: Functions
#!/usr/bin/env bash
make_and_enter() {
mkdir -p "$1"
cd "$1"
}
make_and_enter $1
61
Bash Scripting: Functions
#!/usr/bin/env bash
make_and_enter() {
mkdir -p "$1"
cd "$1"
}
make_and_enter $1
62
Bash Scripting: Functions
#!/usr/bin/env bash
make_and_enter() {
mkdir -p "$1"
cd "$1"
}
make_and_enter $1
63
Bash Scripting: Exercise
For my name, my function would create a folder named ayelet and a file
named [Link] inside of ayelet.
64
Bash Scripting: Exercise
#!/usr/bin/env bash
make_my_folder() {
mkdir "$1"
cd "$1"
touch "$2"
}
make_my_folder $1 $2
65
Bash Scripting: Return Values
The notion of exit codes allows for verifying the success or failure of a
previous command.
66
Bash Scripting: Return Values
The notion of exit codes allows for verifying the success or failure of a
previous command.
An exit code or return value is the way scripts or commands can
communicate with each other about how execution went.
67
Bash Scripting: Return Values
The notion of exit codes allows for verifying the success or failure of a
previous command.
An exit code or return value is the way scripts or commands can
communicate with each other about how execution went.
A return value of 0 means that everything went OK. A return value other
than 0 means that an error occurred.
68
Bash Scripting: Return Values
The notion of exit codes allows for verifying the success or failure of a
previous command.
An exit code or return value is the way scripts or commands can
communicate with each other about how execution went.
A return value of 0 means that everything went OK. A return value other
than 0 means that an error occurred.
$? provides the return value from the most recently executed command
69
Bash Scripting: Return Values
If you ever need a placeholder for a command that succeeds or fails, you
can use the true and false commands.
70
Bash Scripting: Return Values
If you ever need a placeholder for a command that succeeds or fails, you
can use the true and false commands.
71
Bash Scripting: Return Values
adrazen@ayelet-computer ~ % sh success_or_failure.sh
#!/usr/bin/env bash
result=$(($RANDOM % 2))
if [ $result -eq 0 ]
then
true
echo "$?"
else
false
echo "$?"
fi 73
Bash Scripting: Return Values
73
Bash Scripting: Return Values
74
Bash Scripting: Return Values
75
Bash Scripting: Return Values
76
Bash Scripting: Exercise
#!/usr/bin/env bash
cat $1
if [ $? -eq 0 ]
then
echo "File exists!"
else
echo "File does not exist!"
fi
78
Bash Scripting: Exercise
#!/usr/bin/env bash
79
Bash Scripting: Exercise
#!/usr/bin/env bash
80
Bash Scripting: Exercise
#!/usr/bin/env bash
81
Bash Scripting: Command Substitution
82
Bash Scripting: Command Substitution
Example:
#!/usr/bin/env bash
Bash scripting has some specific syntax that is worth calling out.
If you're ever stuck, look something up
84
Bash Scripting: [ vs [[
When you have an if-statement, you need to encapsulate the condition. You
can do this in two ways:
85
Bash Scripting: [ vs [[
When you have an if-statement, you need to encapsulate the condition. You
can do this in two ways:
if [ condition ] if [[ condition ]]
then then
# do something # do something
fi fi
86
Bash Scripting: [ vs [[
When you have an if-statement, you need to encapsulate the condition. You
can do this in two ways:
if [ condition ] if [[ condition ]]
then then
# do something # do something
fi fi
87
Bash Scripting: [ vs [[
When you have an if-statement, you need to encapsulate the condition. You
can do this in two ways:
if [ condition ] if [[ condition ]]
88
Bash Scripting: [ vs [[
When you have an if-statement, you need to encapsulate the condition. You
can do this in two ways:
if [ condition ] if [[ condition ]]
89
Bash Scripting: [ vs [[
When you have an if-statement, you need to encapsulate the condition. You
can do this in two ways:
if [ condition ] if [[ condition ]]
90
Bash Scripting: [ vs [[
When you have an if-statement, you need to encapsulate the condition. You
can do this in two ways:
if [ 1 < 2 ] if [[ 1 < 2 ]]
then then
echo "Correct!" echo "Correct!"
fi fi
91
Bash Scripting: [ vs [[
When you have an if-statement, you need to encapsulate the condition. You
can do this in two ways:
if [ 1 < 2 ] if [[ 1 < 2 ]]
then then
echo "Correct!" echo "Correct!"
fi fi
92
Bash Scripting: [ vs [[
When you have an if-statement, you need to encapsulate the condition. You
can do this in two ways:
if [ 1 < 2 ] if [[ 1 < 2 ]]
then then
echo "Correct!" echo "Correct!"
fi fi
2: No such file or
directory
93
Bash Scripting: [ vs [[
When you have an if-statement, you need to encapsulate the condition. You
can do this in two ways:
if [ 1 < 2 ] if [[ 1 < 2 ]]
then then
echo "Correct!" echo "Correct!"
fi fi
2: No such file or
directory
94
Bash Scripting: [ vs [[
When you have an if-statement, you need to encapsulate the condition. You
can do this in two ways:
if [ 1 < 2 ] if [[ 1 < 2 ]]
then then
echo "Correct!" echo "Correct!"
fi fi
95
Bash Scripting: [ vs [[
When you have an if-statement, you need to encapsulate the condition. You
can do this in two ways:
if [ condition ] if [[ condition ]]
96
Bash Scripting: [ vs [[
When you have an if-statement, you need to encapsulate the condition. You
can do this in two ways:
if [ condition ] if [[ condition ]]
In general, single brackets are recognized by more scripting languages and
are POSIX compliant. (Won't work with sh interpreter unless linked to bash.)
97
Bash Scripting: [ vs [[
When you have an if-statement, you need to encapsulate the condition. You
can do this in two ways:
if [ condition ] if [[ condition ]]
In general, single brackets are recognized by more scripting languages and
are POSIX compliant. (Won't work with sh interpreter unless linked to bash.)
Double brackets are less portable, but they align with what you would expect
from high level coding languages. You can use comparison operators such
as < or > and logical operators such as && or ||.
98
Bash Scripting: Comparison
99
Bash Scripting: Comparison
100
Bash Scripting: Comparison
101
Bash Scripting: Comparison
102
Bash Scripting: Comparison
103
Bash Scripting: Comparison
104
Bash Scripting: Comparison
105
Bash Scripting: Comparison
106
Bash Scripting: Comparison
107
Bash Scripting: Comparison
108
Bash Scripting: Comparison
109
Bash Scripting: Comparison
110
Bash Scripting: Arithmetic
111
Bash Scripting: Arithmetic
112
Bash Scripting: Arithmetic
113
Bash Scripting: Arithmetic
114
Bash Scripting: Exercise
115
Bash Scripting: Exercise
#!/usr/bin/env bash
time=$(date +%H)
if [ $time -gt 5 ] && [ $time -lt 12 ]
then
echo "Good morning!"
elif [ $time -gt 12 ] && [ $time -lt 18 ]
then
echo "Good evening!"
elif [ $time -gt 18 ] && [ $time -lt 5 ]
then
echo "Good night!"
fi 117
A d v a n c e d Running
You can turn your shell script into a "command" by moving it to ~/bin.
For example if you have a script called hello, you could do the
following:
adrazen@ayelet-computer ~ % mv hello ~/bin/
Note: this probably won't work yet on your computer but we will learn
about it in a later lecture.
117
S p o t t h e P r o b l e m!
118
Spot It!
If we run uni on the file on the left, will the output look like what's on the right?
q
INPUT OUTPUT
apple apple
banana banana
apple orange
orange kiwi
orange strawberry
kiwi
orange
strawberry
strawberry
apple
119
Spot It!
If we run uni on the file on the left, will the output look like what's on the right?
q
INPUT OUTPUT
apple apple
banana banana
apple orange
orange kiwi
orange orange
kiwi strawberry
orange apple
strawberry
strawberry
apple
120
Spot It!
If we run uni on the file on the left, will the output look like what's on the right?
q
INPUT OUTPUT
apple apple
apple banana
apple orange
banana kiwi
orange strawberry
orange
orange
kiwi
strawberry
strawberry
121
Spot It!
Will the following command work to replace all instances of the string world
with the string wOrLd?
cat [Link] | sed 's/world/wOrLd/'
[Link]
Hello world
It's a small world
The world is my oyster
On top of the world
A world away
Do someone a world of good
122
Spot It!
Will the following command work to replace all instances of the string world
with the string wOrLd? → No.
cat [Link] | sed 's/world/wOrLd/g'
[Link]
Hello world
It's a small world
The world is my oyster
On top of the world
A world away
Do someone a world of good
123
Spot It!
num=101
if [$num -gt 100]
then
echo "That's a big number!"
fi
124
Spot It!
num=101
if [ $num -gt 100 ]
then
echo "That's a big number!"
fi
125