0% found this document useful (0 votes)
3 views19 pages

OS Shell Scripting Guide

This document is a study guide for beginners on shell scripting, covering essential concepts and six specific scripts: Prime Number Check, Leap Year Check, Palindrome Number Check, Armstrong Number Check, and Fibonacci Series. It provides detailed explanations of shell scripting fundamentals, including the shebang line, variables, conditionals, loops, and arithmetic operations. Each script is accompanied by a line-by-line explanation and examples to help learners understand how to write and execute shell scripts effectively.

Uploaded by

AMAN KUMAR SHAW
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views19 pages

OS Shell Scripting Guide

This document is a study guide for beginners on shell scripting, covering essential concepts and six specific scripts: Prime Number Check, Leap Year Check, Palindrome Number Check, Armstrong Number Check, and Fibonacci Series. It provides detailed explanations of shell scripting fundamentals, including the shebang line, variables, conditionals, loops, and arithmetic operations. Each script is accompanied by a line-by-line explanation and examples to help learners understand how to write and execute shell scripts effectively.

Uploaded by

AMAN KUMAR SHAW
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Operating Systems Lab

Assignment 3 — Shell Scripting Study Guide

Prime • Leap Year • Palindrome • Armstrong • Fibonacci • Decimal to Binary

Written for beginners — no prior Shell or Linux knowledge assumed.

This guide covers every concept you need to understand and explain your 6 shell scripts: what shell
scripting is, how each script works line by line, and a complete set of viva questions you should be
ready to answer.
Part 0: What Is Shell Scripting? — The Big
Picture
Before we look at a single line of code, we need to answer a fundamental question: what exactly is a shell,
and why do we write scripts for it? If you skip this section, the syntax in your assignments will feel like
random symbols.

0.1 What Is a Shell?


When you open a terminal on Linux and type a command like ls or cd Documents, you are talking to the
shell. The shell is a program that reads what you type, interprets it, and sends the appropriate instructions
to the Operating System kernel. Think of it as a translator sitting between you (a human) and the OS (a
machine).

Analogy: The OS kernel is like a powerful engine inside a car. You do not control the engine directly
— you use the steering wheel and pedals. The shell is that interface: it translates your
human-readable commands into precise instructions the engine can act on.

0.2 What Is a Shell Script?


A shell script is simply a text file full of shell commands, saved with a .sh extension, that you can run all at
once. Instead of typing ten commands one by one in a terminal, you write them in a file and the shell
executes them in sequence. This is the foundation of automation in Linux systems.

Your assignments use Bash (Bourne Again SHell), which is the most common shell on Linux systems.
Every script begins with the line #!/bin/bash — called a shebang — which tells the OS exactly which
program should interpret the script.

0.3 The Shebang Line — #!/bin/bash


#!/bin/bash
# This is the very first line of every Bash script.
# The #! is called a 'shebang'. /bin/bash is the path to the Bash interpreter.
# Without this line, the OS doesn't know HOW to run your script.

When you run a script with ./[Link], the OS reads the first two characters #! and immediately follows
the path that comes after them to find the right interpreter. So #!/bin/bash means 'run this file using the
Bash shell located at /bin/bash'.

0.4 Essential Bash Concepts You Must Know


Variables

name='Alice' # Assign a value — NO spaces around =


echo $name # Use the variable by putting $ before its name
num=42
echo $num # Output: 42

Variables in Bash have no type — everything is treated as text by default. When you want to do arithmetic,
you need special syntax, explained below. The most critical rule is: no spaces around the = sign when
assigning. num = 42 is wrong in Bash; it tries to run a command called 'num' with arguments.

Reading Input from the User

echo 'Enter your name:' # Print a prompt to the screen


read name # Read what the user types and store it in $name
echo "Hello, $name" # Use it — note: double quotes allow $variable expansion

Arithmetic — The $(( )) Syntax


Bash does not automatically perform arithmetic like most programming languages. To do math, you must
wrap the expression in double parentheses: $(( )). This is the arithmetic expansion syntax, and you will see
it in every one of your six scripts.

a=10
b=3
echo $((a + b)) # Addition: 13
echo $((a - b)) # Subtraction: 7
echo $((a * b)) # Multiplication: 30
echo $((a / b)) # Division: 3 (integer division — remainder dropped)
echo $((a % b)) # Modulo: 1 (remainder of 10 / 3)

Conditionals — if [ ] and (( ))

# Square bracket syntax for string/number comparisons:


if [ $num -eq 5 ] # -eq means 'equals' for numbers
then
echo 'Five!'
fi # 'fi' is just 'if' backwards — it closes the if block
# Double parenthesis syntax for arithmetic conditions:
if (( num % 2 == 0 )) # More natural math syntax, like C/Java
then
echo 'Even!'
fi

Key comparison operators in [ ] (square bracket) syntax:

• -eq equals -ne not equal -lt less than -le less than or equal -gt greater than -ge greater
than or equal
Inside (( )) you can use ==, !=, <, <=, >, >= just like C/Java.

Loops — for and while

# C-style for loop — same idea as C/C++:


for (( i=1; i<=5; i++ ))
do
echo $i
done
# While loop — runs as long as the condition is true:
num=10
while [ $num -gt 0 ]
do
echo $num
num=$((num - 1)) # Decrement manually — Bash has no num--
done

The exit Command


The exit command immediately stops the script at that point. You will see it used in the Prime Number
script to stop execution as soon as a non-prime condition is found. It is the Bash equivalent of a return or
break-out-of-everything in other languages.
Part 1: Script 1 — Prime Number Check

1.1 What Is a Prime Number?


A prime number is any integer greater than 1 that has no divisors other than 1 and itself. For example, 7 is
prime because nothing divides it evenly except 1 and 7. The number 6 is not prime because 2 divides it
evenly (6 ÷ 2 = 3). By definition, 0 and 1 are not prime.

1.2 The Algorithm


To check if a number N is prime, we try dividing it by every integer from 2 up to N/2. If any of these
divisions produce a remainder of zero (using the modulo operator %), then N has a factor and is not prime.
If none of them divide evenly, N is prime. We only need to go up to N/2 because any factor larger than N/2
would require a corresponding factor smaller than 2, which cannot exist for integers.

1.3 Full Code With Line-by-Line Explanation


#!/bin/bash
echo "Enter a number:"
read num
# Rule: numbers <= 1 are never prime — handle this edge case first
if [ $num -le 1 ]
then
echo "Not Prime"
exit # Stop the script immediately
fi
# Try every divisor from 2 up to num/2
for (( i=2; i<=num/2; i++ ))
do
# If num divided by i has remainder 0, i is a factor — not prime
if [ $((num % i)) -eq 0 ]
then
echo "Not Prime"
exit # No need to check further — we found a factor
fi
done
# If we reach here, no factor was found — it is prime
echo "Prime"

1.4 Trace Through an Example


Let us trace the script manually for num = 7. 7 is greater than 1, so we skip the first check. The loop runs
for i = 2, 3 (since 7/2 = 3 in integer division). 7 % 2 = 1 (not zero), 7 % 3 = 1 (not zero). Loop ends. We
reach the final echo and print Prime.

Now trace for num = 9. 9 is greater than 1. Loop runs for i = 2, 3, 4. 9 % 2 = 1, 9 % 3 = 0 — remainder is
zero! Script immediately prints Not Prime and exits.

Why exit instead of break?

Using break would only exit the for loop; the script would then continue and print 'Prime' — which
would be wrong! Using exit terminates the entire script the moment a factor is found, preventing any
further output.

Part 2: Script 2 — Leap Year Check

2.1 What Is a Leap Year?


A leap year has 366 days (with February having 29 days) instead of the usual 365. This correction
accounts for the fact that Earth takes approximately 365.25 days to orbit the Sun. The rule for determining
a leap year has two parts, combined with a special exception.

2.2 The Leap Year Rule


A year is a Leap Year if:

• It is divisible by 400 (e.g., 1600, 2000, 2400) OR

• It is divisible by 4 AND not divisible by 100 (e.g., 2024, 1996)

Important: Years divisible by 100 but NOT by 400 are NOT leap years. So 1900 is not a leap year,
but 2000 is.

2.3 Full Code With Line-by-Line Explanation


#!/bin/bash
echo "Enter a year:"
read year
# Double parenthesis (( )) allows natural arithmetic and logical operators
# || means OR, && means AND, == means equals, != means not equals
if (( (year % 400 == 0) || (year % 4 == 0 && year % 100 != 0) ))
then
echo "Leap Year"
else
echo "Not a Leap Year"
fi
2.4 Why This Condition Works
The condition is evaluated using short-circuit logic. If year % 400 == 0 is true, the whole OR expression is
immediately true — no need to check the second part. If the first part is false, Bash checks the second
part: year % 4 == 0 AND year % 100 != 0. This correctly handles the century-year exception in one clean
line.

Year % 400 == 0? % 4 == 0? % 100 == 0? Leap Year?

2000 Yes Yes Yes YES — divisible by 400

1900 No Yes Yes NO — divisible by 100 but


not 400

2024 No Yes No YES — divisible by 4, not


100

2023 No No No NO — not divisible by 4


Part 3: Script 3 — Palindrome Number Check

3.1 What Is a Palindrome?


A palindrome is something that reads the same forwards and backwards. For numbers, 121, 1331, and
12321 are palindromes. The number 123 is not, because reversed it becomes 321 which is different. The
algorithm works by mathematically reversing the digits of the number and comparing the result to the
original.

3.2 The Digit-Reversal Algorithm


The algorithm extracts digits one at a time from the right using modulo 10 (which gives the last digit), builds
the reversed number by multiplying the current reverse by 10 and adding the new digit, then removes the
last digit from the original by integer-dividing by 10. This repeats until the original number becomes 0.

Example trace for num = 121:

Iteration num digit = num % 10 reverse = reverse*10 + digit num = num / 10

Start 121 — reverse = 0 —

1 121 1 0*10+1 = 1 12

2 12 2 1*10+2 = 12 1

3 1 1 12*10+1 = 121 0

End 0 (loop stops) — reverse = 121 original = 121 ✓ Palindrome

3.3 Full Corrected Code With Explanation


The original Assignment 3 code for this script has capitalisation errors — Bash keywords like Echo,
Read, While, Do, Done, If, Then, Else, Fi must be written in lowercase. Bash is case-sensitive. The
corrected version is below.

#!/bin/bash
echo "Enter a number:"
read num
original=$num # Save a copy of the original before we modify num
reverse=0
while [ $num -gt 0 ] # Keep going while there are digits left
do
digit=$((num % 10)) # Extract the last digit
reverse=$((reverse * 10 + digit)) # Append digit to the right of reverse
num=$((num / 10)) # Remove the last digit from num
done
if [ $original -eq $reverse ] # Compare reversed number to original
then
echo "Palindrome"
else
echo "Not Palindrome"
fi

Why save a copy in $original?

The while loop destroys $num by dividing it repeatedly until it becomes 0. If we didn't save the original
value first, we would have nothing to compare the reversed number against at the end. This is why
line 4 saves a copy before the loop begins.

Part 4: Script 4 — Armstrong Number Check

4.1 What Is an Armstrong Number?


An Armstrong number (also called a Narcissistic number) is a number where the sum of the cubes of its
individual digits equals the number itself. Your assignment specifically checks for 3-digit Armstrong
numbers (using cube power). The classic examples are 153 (1³ + 5³ + 3³ = 1 + 125 + 27 = 153) and 370 (3³
+ 7³ + 0³ = 27 + 343 + 0 = 370).

Note on the definition: A fully general Armstrong number uses the number of digits as the power (so
a 4-digit number would use 4th power). Your assignment uses cube (power of 3) specifically, which
works correctly for 3-digit numbers.

4.2 Full Code With Line-by-Line Explanation


#!/bin/bash
echo "Enter a number:"
read num
original=$num # Save original for final comparison
sum=0 # This will accumulate the sum of cubed digits
while [ $num -gt 0 ]
do
digit=$((num % 10)) # Extract last digit
sum=$((sum + digit*digit*digit)) # Add digit cubed to sum
num=$((num / 10)) # Remove last digit
done
# If sum of cubed digits == original number, it is Armstrong
if [ $sum -eq $original ]
then
echo "Armstrong Number"
else
echo "Not an Armstrong Number"
fi

4.3 Trace for num = 153


Iteration num digit digit³ sum

Start 153 — — 0

1 153 3 27 27

2 15 5 125 152

3 1 1 1 153

End 0 — — 153 == 153 ✓ Armstrong


Part 5: Script 5 — Fibonacci Series

5.1 What Is the Fibonacci Series?


The Fibonacci series is a sequence where each number is the sum of the two numbers before it. It starts
with 0 and 1, and each subsequent term is found by adding the previous two: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34
...

The algorithm needs to track two variables — let's call them a (current) and b (next). At each step, we print
a, calculate the new next term, then shift both variables forward.

5.2 Full Corrected Code With Explanation


Like the Palindrome script, the original Fibonacci code has capitalisation errors. Below is the corrected
version.

#!/bin/bash
echo "Enter number of terms:"
read n
a=0 # First Fibonacci number
b=1 # Second Fibonacci number
echo "Fibonacci Series:"
for (( i=1; i<=n; i++ ))
do
echo -n "$a " # Print current term; -n prevents newline (stays on same line)
temp=$((a + b)) # Calculate the NEXT term before overwriting a
a=$b # Shift: a moves to where b was
b=$temp # Shift: b moves to the new next term
done
echo # Print a newline at the end (because echo -n suppressed them all)

5.3 Why Do We Need a temp Variable?


This is a classic 'swap' problem. We cannot write a=$b; b=$((a+b)) directly, because by the time we
calculate a+b on the second line, 'a' has already been overwritten with the new value. The temp variable
preserves the sum before we start overwriting anything. Always calculate first, then assign.

i Print a temp = a+b a=b b = temp

1 0 0+1=1 1 1

2 1 1+1=2 1 2

3 1 1+2=3 2 3

4 2 2+3=5 3 5
5 3 3+5=8 5 8

Part 6: Script 6 — Decimal to Binary Conversion

6.1 How Does Decimal to Binary Conversion Work?


Every decimal (base-10) number can be expressed in binary (base-2) using only 0s and 1s. The algorithm
works by repeatedly dividing the number by 2 and collecting the remainders. The remainders, read from
bottom to top (last-to-first), form the binary representation.

Example: Convert 13 to binary.

Step num num ÷ 2 Remainder (num % 2) binary string

1 13 6 1 "1" + "" = "1"

2 6 3 0 "0" + "1" = "01"

3 3 1 1 "1" + "01" = "101"

4 1 0 1 "1" + "101" = "1101"

End 0 (stop) — — 1101 = 13 in binary ✓

6.2 Full Code With Line-by-Line Explanation


#!/bin/bash
echo "Enter a decimal number:"
read num
binary="" # Start with an empty string
while [ $num -gt 0 ]
do
rem=$((num % 2)) # Get the remainder: either 0 or 1
binary="$rem$binary" # Prepend rem to binary (builds right-to-left correctly)
num=$((num / 2)) # Divide by 2 (integer division)
done
echo "Binary number: $binary"

6.3 The Key Trick — Prepending Instead of Appending


The magic is in the line binary="$rem$binary". We put the new remainder BEFORE the existing binary
string (prepend), not after (append). This is necessary because the division-by-2 algorithm generates bits
from least-significant to most-significant — the last remainder calculated is actually the leftmost (highest)
bit. By prepending, the final string is already in the correct order.
String concatenation in Bash: There is no + operator for strings. You concatenate by placing
variables directly next to each other inside double quotes. So binary="$rem$binary" means: create
a new string made of the value of rem followed by the value of binary.
Part 7: Complete Viva Questions and Answers
This section covers every angle an examiner might probe — from basic shell syntax to deep logic
questions about each script. Questions are ordered from basic to advanced.

Category A: Shell Basics

Q: What is a shell script?

A: A shell script is a text file containing a sequence of shell commands that can be executed as a
single program. It allows automation of repetitive tasks in a Linux/Unix environment. Shell scripts are
interpreted line by line by the shell program, not compiled.

Q: What does #!/bin/bash mean?

A: It is called a shebang line. The #! characters tell the OS that this is a script file, and /bin/bash is the
path to the Bash interpreter that should execute it. Without this line, the OS does not know which
interpreter to use.

Q: What is the difference between single quotes and double quotes in Bash?

A: Double quotes allow variable expansion — $variable inside double quotes is replaced by its value.
Single quotes treat everything literally — $variable inside single quotes is printed as the literal text
'$variable', not its value.

Q: What does the read command do?

A: The read command pauses the script and waits for the user to type input. Whatever the user types
is stored in the named variable. For example, 'read num' stores the typed value in the variable $num.

Q: What is the modulo operator and what does % do in Bash?

A: The modulo operator % gives the remainder of integer division. For example, 7 % 3 = 1 because 7
divided by 3 gives 2 with a remainder of 1. It is used in nearly every mathematical script to extract
digits, check divisibility, and reverse numbers.

Q: What is the difference between [ ] and (( )) in Bash conditions?

A: Square brackets [ ] use a special comparison syntax with flags like -eq, -lt, -gt for numbers and =
for strings. Double parentheses (( )) use standard arithmetic operators like ==, <, >, &&, || and are
generally more natural for mathematical conditions.
Q: What does echo -n do?

A: Normally, echo prints its output followed by a newline character, moving the cursor to the next line.
The -n flag suppresses this newline, so the next echo output appears on the same line. The Fibonacci
script uses this to print all terms on one line separated by spaces.

Q: Why are Bash keywords case-sensitive?

A: Bash, like most Unix tools, follows Unix conventions where identifiers are case-sensitive. The
interpreter only recognises keywords like 'if', 'then', 'while', 'do', 'done', 'fi' in lowercase. Writing 'If' or
'While' causes Bash to look for a command with that exact name, which does not exist, resulting in a
'command not found' error.

Category B: Script-Specific Logic

Q: Why does the prime number script check up to num/2 and not num?

A: If a number N has a divisor d greater than N/2, then N/d would be less than 2, which is impossible
for integer divisors. So no factor of N can be larger than N/2. This optimisation halves the number of
iterations needed.

Q: What happens in the prime script if the input is 2?

A: 2 is greater than 1, so it passes the first check. The for loop runs for i from 2 to 2/2 = 1. Since the
starting value 2 is greater than the ending value 1, the loop body never executes. The script reaches
the final echo and prints 'Prime'. This is correct — 2 is prime.

Q: Explain the leap year condition: (year % 400 == 0) || (year % 4 == 0 && year % 100 != 0).

A: This is a direct implementation of the Gregorian calendar rule. The first part handles century years
divisible by 400 (always leap years, like 2000). The second part handles regular years: divisible by 4
but not by 100 (like 2024, 1996). The year 1900 fails because it is divisible by 100 but not 400.

Q: Why do we save the original number before the palindrome/armstrong loop?

A: The while loop modifies the variable by dividing it by 10 repeatedly until it reaches 0. Once the loop
finishes, the original variable holds 0. We need the original value to compare against the reversed
number (palindrome) or the digit sum (Armstrong). Saving a copy before the loop preserves this
value.

Q: What is the purpose of the temp variable in the Fibonacci script?

A: The temp variable stores the sum a+b before we overwrite a. If we wrote 'a=$b' first and then
'b=$((a+b))', the value of 'a' would already be the new value, giving a wrong result. temp acts as a
safe holding place during the simultaneous shift of both variables.
Q: Why does the binary conversion script use binary="$rem$binary" instead of
binary="$binary$rem"?

A: The division-by-2 algorithm produces the least significant bit (rightmost) first. Appending with
$binary$rem would build the number backwards. Prepending with $rem$binary places each new bit
to the left of all previously found bits, which naturally produces the correct binary representation from
most significant to least significant.

Q: What is the binary representation of 10, and can you trace the script?

A: 10 in binary is 1010. Trace: 10%2=0, binary='0', num=5. 5%2=1, binary='10', num=2. 2%2=0,
binary='010', num=1. 1%2=1, binary='1010', num=0. Loop ends. Output: 1010.

Category C: Algorithms and Mathematical Concepts

Q: What are some Armstrong numbers for 3 digits?

A: The 3-digit Armstrong numbers are 153, 370, 371, and 407. Verification: 3³+7³+1³ = 27+343+1 =
371 ✓. These are the only four 3-digit numbers where the sum of cubed digits equals the number
itself.

Q: Can the palindrome script handle 0 as input? What happens?

A: The while loop condition is [ $num -gt 0 ], which is false for 0. The loop never executes, reverse
remains 0, and original is 0. Since 0 equals 0, the script prints 'Palindrome'. This is mathematically
reasonable — 0 reads the same forwards and backwards.

Q: What is the time complexity of the prime check algorithm?

A: The algorithm runs in O(N/2) time, which simplifies to O(N). A more efficient version would check
only up to the square root of N, giving O(√N) complexity, but your assignment uses the N/2 approach
which is sufficient for the scope of this lab.

Q: Name five Fibonacci numbers and the term number that generates them.

A: Term 1: 0. Term 2: 1. Term 3: 1. Term 4: 2. Term 5: 3. Term 6: 5. Term 7: 8. Term 8: 13. Each term
is the sum of the two immediately before it.

Q: What would happen in the decimal-to-binary script if the input is 0?

A: The while loop condition [ $num -gt 0 ] would be false immediately for 0, so the loop never
executes. The variable 'binary' remains an empty string. The script would print 'Binary number: ' with
nothing after it. In a production script, you would add a special case to handle 0 and print '0'.

Category D: Common Mistakes and Debugging


Q: What happens if you write num=num+1 instead of num=$((num+1))?

A: Bash would treat num+1 as a literal string and assign the text 'num+1' to the variable num. There
would be no arithmetic. This is one of the most common beginner mistakes in Bash. All arithmetic in
Bash must be performed inside $(( )).

Q: What happens if you write if[$num -eq 0] without spaces?

A: The command would fail with a 'command not found' error because Bash looks for a command
literally called 'if[$num'. The square brackets in Bash are actually a command called 'test', and they
require spaces on all sides: [ $num -eq 0 ].

Q: What is the bug in the original Q3 and Q5 code from the assignment?

A: The original code uses capitalised keywords: Echo, Read, While, Do, Done, If, Then, Else, Fi, For.
Bash is case-sensitive and only recognises these as lowercase keywords. Capitalised versions are
treated as command names, causing 'command not found' errors at runtime.

Q: How would you run a shell script from the terminal?

A: First, make the script executable: chmod +x [Link]. Then run it: ./[Link]. Alternatively, you can
invoke the interpreter directly: bash [Link] — this does not require the file to have execute
permissions.
Part 8: Quick Revision Cheat Sheet

8.1 Bash Syntax at a Glance


variable=value # Assign (no spaces around =)
$variable # Use variable
$((expr)) # Arithmetic
read varname # Read user input
echo "text $var" # Print with variable expansion
echo -n "text " # Print without newline
[ $a -eq $b ] # Compare numbers: -eq -ne -lt -le -gt -ge
(( a == b && c != d )) # Arithmetic conditions
if...then...else...fi # Conditional
while [ cond ]; do...done # While loop
for (( i=0; i<n; i++ )); do...done # C-style for loop
exit # Terminate script immediately

8.2 All Six Scripts — Key Ideas


Script Core Algorithm Key Operator Watch Out For

Prime Divide by i from 2 to N/2; if % (modulo) Use exit not break; handle <=1
remainder==0, not prime separately

Leap Year Divisible by 400 OR (by 4 AND not || and && Century exception: 1900 is
100) NOT a leap year

Palindrome Extract digits via %10, build % 10 and / 10 Save original before loop; use
reverse, compare to original lowercase keywords

Armstrong Extract digits via %10, add digit³ to digit*digit*digit Only correct for 3-digit numbers
sum, compare to original as written

Fibonacci Print a, temp=a+b, a=b, b=temp, Swap via temp temp prevents overwrite bug;
repeat n times echo -n for inline print

Dec→Binary Remainder of div by 2; prepend to Prepend: Prepend not append; empty


string; divide by 2 "$rem$binary" string edge case for 0

Final tip for your viva:

For every script, be ready to: (1) explain what the problem is mathematically, (2) trace through a
specific example by hand, and (3) explain why each line of code is written the way it is. Examiners
love asking 'what would happen if...' questions — the answers are all covered in Category D of the
viva section above.

End of Study Guide


Understand the logic, not just the syntax — that is what earns full marks.

You might also like