SHELL SCRIPTING
SHELL SCRIPTING
___
Notes
echo $0
3. Writing Content in vi
Let’s create a simple script that prints "Hello, World!" and displays the
current date and time. With vi in insert mode, type the following script:
#!/bin/bash
date
Multi-Line Comments:
Bash does not have a direct syntax for multi-line comments, but you can
simulate it using a here-document with <<.
: <<'COMMENT'
COMMENT
Alternatively, use the << syntax directly:
<<comment
It won’t be executed.
comment
Output:
Hello World!
echo "${myArray[1]}"
Outputs: 2
This fetches all elements starting from the second element (index 1).
● To get a specific range of values:
echo "${myArray[*]:1:2}"
myArray+=(5 6 8)
Access Values:
echo "${myArray[name]}"
Update Array:
myArray+=( [city]=NewYork )
Length:
Replace:
echo ${str/Scripting/Programming} Outputs: Shell Programming
Extract Substring:
echo ${str:6:9} Outputs: Scripting
Convert to uppercase:
upper=${myVar^^}
echo $upper Output: HELLO WORLD!
Convert to lowercase:
lower=${myVar,,}
echo $lower Output: hello world!
Replace a substring:
replace=${myVar/World/Buddy}
echo $replace Output: Hello Buddy!
● Basic Input:
read var_name
echo "You entered: $var_name"
Example Output:
(User types "John")
You entered: John
Example Output:
(Your name: User types "John")
Your name: John
Hello, John!
Key Difference:
🔹 Arithmetic Operations
Increment:
((a++))
Key Difference:
● let is more traditional, while (( )) is more modern and allows for more
complex arithmetic expressions.
fi
if-else Statement:
if [ $a -gt $b ]; then
else
fi
else
fi
Case Statement:
case $a in
esac
Key Notes:
Comparison Operators
Greater Than or Equal to: -ge: Checks if the left operand is greater than or
equal to the right.
[ $a -ge $b ]
Less Than or Equal to: -le: Checks if the left operand is less than or equal to
the right.
[ $a -le $b ]
Not Equal to: -ne or !=: Checks if two values are not equal.
[ $a -ne $b ]
Greater Than: -gt: Checks if the left operand is greater than the right.
[ $a -gt $b ]
Less Than: -lt: Checks if the left operand is less than the right.
[ $a -lt $b ]
🔹 Logical Operators
Using && (AND) Operator:
a=10
b=5
if [ $a -gt 5 ] && [ $b -lt 10 ]; then
echo "Both conditions are true"
else
echo "One or both conditions are false"
fi
Explanation:
a=10
[ $a -gt 5 ] && echo "Greater" || echo "Not Greater"
Explanation:
🔄 For Loop
The for loop iterates over a list or a range of values and performs actions for
each item.
Syntax:
for item in list; do
# Commands to execute for each item
done
Example:
for i in 1 2 3; do
echo "Number: $i"
done
Output:
Number: 1
Number: 2
Number: 3
Range Example:
for i in {1..3}; do
echo "Count: $i"
done
Output:
Count: 1
Count: 2
Count: 3
🔄 While Loop
The while loop runs as long as the specified condition is true.
Syntax:
while [ condition ]; do
# Commands to execute
done
Example:
count=1
while [ $count -le 3 ]; do
echo "Count is: $count"
((count++)) # Increment count
done
Output:
Count is: 1
Count is: 2
Count is: 3
🔄 Until Loop
The until loop continues to execute until the condition becomes true.
Syntax:
until [ condition ]; do
# Commands to execute
done
Example:
count=1
until [ $count -gt 3 ]; do
echo "Count is: $count"
((count++))
done
Output:
Count is: 1
Count is: 2
Count is: 3
🔄 Infinite Loop
An infinite loop continues running indefinitely until it is manually stopped (e.g.,
using Ctrl+C).
for (( ; ; )); do
done
While Infinite Example:
while :; do
done
until false; do
done
...
🖥️ Select Loop
The select loop creates a simple menu system, which allows users to select an
option from a list. It's useful when you need a user-driven selection process.
Syntax:
select option in list; do
# Commands based on user choice
done
Example:
PS3="Choose a fruit: "
select fruit in Apple Banana Orange Exit; do
case $fruit in
Apple) echo "You chose Apple";;
Banana) echo "You chose Banana";;
Orange) echo "You chose Orange";;
Exit) break;;
*) echo "Invalid option";;
esac
done
Example Output:
1) Apple
2) Banana
3) Orange
4) Exit
Choose a fruit: 2
You chose Banana
Explanation:
● PS3 sets the prompt message.
● The select loop displays options, and each selection runs the
corresponding case statement.
● The break statement exits the loop when the user selects "Exit."
🔄 Functions
1. Defining Functions:
2. Basic Function:
Functions can accept arguments, which are accessed via $1, $2, etc.
greet_user() {
echo "Hello, $1!"
}
greet_user "Adhyansh"
4. Return Values:
Functions return values via echo, and the output can be captured.
add_numbers() {
result=$(( $1 + $2 ))
echo $result
}
sum=$(add_numbers 3 5)
echo "The sum is: $sum"
6. Recursion:
Functions can call themselves recursively.
factorial() {
if [ $1 -le 1 ]; then
echo 1
else
prev=$(factorial $(( $1 - 1 )))
echo $(( $1 * prev ))
fi
}
result=$(factorial 5)
echo "Factorial of 5 is: $result"
7. Default Values:
greet() {
local name=${1:-Guest}
echo "Hello, $name!"
}
greet "Adhyansh" Output: "Hello, Adhyansh!"
greet Output: "Hello, Guest!"
Bash doesn't directly support passing by reference but can simulate it using
eval.
modify_value() {
eval $1=\$2
}
modify_value var 100
echo "The value of var is now: $var" Output: "The
value of var is now: 100"
9. Argument Passing:
You can pass arguments to functions, and they can be accessed inside the
function.
Example:
greet() {
echo "Hello, $1! You are $2 years old."
}
greet "Adhyansh" 25
Example:
print_all() {
for arg in "$@"; do
echo "$arg"
done
}
print_all "Apple" "Banana" "Cherry"
Output:
Apple
Banana
Cherry
3. All Arguments as a Single String ($*)
● Similar to $@, but it treats all arguments as a single string, meaning spaces
between arguments may be lost.
Example:
print_all_as_string() {
echo "$*"
}
print_all_as_string "Apple" "Banana" "Cherry"
Output: Apple Banana Cherry
Example:
count_args() {
echo "Number of arguments: $#"
}
count_args "Apple" "Banana" "Cherry"
Output: Number of arguments: 3
Summary
Syntax:
Output:
Original arguments: one, two, three
After shift: two, three
After the shift, $1 becomes "two", and $2 becomes "three".
Output:
Processing argument: arg1
Processing argument: arg2
Processing argument: arg3
Processing argument: arg4
The loop processes each argument one by one by shifting the arguments left until
there are no more arguments ($# becomes 0).
After shifting by 2, the first two arguments are removed, and the remaining
arguments are accessible using $@.
Key Points:
● shift removes the first argument ($1) and shifts the remaining arguments
left.
● You can shift by multiple positions using shift n.
● The $# variable always reflects the remaining number of arguments.
● The shift command is useful in loops for processing a variable number of
arguments.
break Statement
Example:
for i in {1..5}; do
if [ $i -eq 3 ]; then break; fi
echo $i
done
● Purpose: Skips the current loop iteration and moves to the next one.
● Syntax: continue or continue n (skips current iteration in nested loops).
Example:
for i in {1..5}; do
if [ $i -eq 3 ]; then continue; fi
echo $i
done
● Output: Skips iteration when i=3.
Example:
for i in {1..3}; do
for j in {1..3}; do
if [ $i -eq 2 ] && [ $j -eq 2 ]; then break 2; fi
echo "i=$i, j=$j"
done
done
● Output: Exits both loops when i=2 and j=2.
4. sleep Command
Example:
sleep 5 # Pauses for 5 seconds
5. exit Command
● Purpose: Exits a script with a status code (0 for success, non-zero for error).
● Syntax: exit <exit_code>
Example:
exit 1 # Exits with an error status
Example:
mkdir myfolder
Summary
seq command
Output:
1
2
3
4
5
Custom Step Size: You can specify a step size between numbers. For example, to
generate numbers from 1 to 10 with a step size of 2:
seq 1 2 10
Output:
1
3
5
7
9
Generating a Sequence with Decimal Values: You can also use floating-point
numbers with seq. For example, generate numbers from 0 to 1 with a step size of
0.2:
seq 0 0.2 1
Output:
0.0
0.2
0.4
0.6
0.8
1.0
Reverse Sequence: You can reverse the order of the sequence by making the
start number greater than the end number:
seq 5 -1 1
Output:
5
4
3
2
1
Using seq with for Loop: You can use seq in a for loop. For example, printing
numbers from 1 to 5:
Output:
Number: 1
Number: 2
Number: 3
Number: 4
Number: 5
Common Options with seq:
Output:
Number: 1.00
Number: 2.00
Number: 3.00
Number: 4.00
Number: 5.00
-s: Change the separator between numbers. By default, it’s a newline, but you can
change it:
seq -s "," 1 5
Output:
1,2,3,4,5
-w: Pad numbers with leading zeros to make them all the same width:
seq -w 1 5
Output:
01
02
03
04
05
Summary:
Basic Syntax:
{item1,item2,item3}
This will generate a list containing the individual items within the braces.
Output:
apple banana cherry
echo {1..5}
Output:
1 2 3 4 5
Output:
a b c d e
Range with Step Size: You can specify a step size by including it after the range:
echo {1..10..2}
Output:
1 3 5 7 9
Combining Text with Variables: You can use brace expansion to combine static
text with variables:
echo file{1..3}.txt
Output:
file1.txt file2.txt file3.txt
Nested Brace Expansion: You can also nest brace expansions to create more
complex patterns:
echo {A,B}{1,2}
Output:
A1 A2 B1 B2
Multiple Elements in a Single Expansion: You can combine multiple sets of values
within a single brace expansion:
echo {A,B,C}{1,2,3}
Output:
A1 A2 A3 B1 B2 B3 C1 C2 C3
Files and Directories: Brace expansion can also be used to generate multiple file
or directory names:
mkdir dir{1,2,3}
Important Points:
● Brace expansion happens before any other shell operation like variable
expansion or command substitution.
● It is not the same as parameter expansion or globbing. It is handled
directly by the shell before the command is executed.
● No spaces between commas in the braces. It should be {item1,item2}
instead of {item1, item2}.
Summary:
Brace expansion is a powerful feature in the shell that allows you to generate
sequences of strings, numbers, or characters without writing them out explicitly. It
can save time and reduce errors when generating repetitive patterns, filenames,
or arguments.
getopts command
Basic Syntax:
$ ./myscript.sh -b
Option B selected
Example 2: Options with Arguments
You can also specify options that require arguments (e.g., -f filename).
$ ./myscript.sh -n 123
Option N selected with argument: 123
For options that have both short and long forms, you can use getopts to handle
short options (e.g., -f) but long options require additional parsing logic. Here's an
example for a simple long-option-like approach.
Example:
#!/bin/bash
if [ $# -eq 0 ]; then
exit 1
fi
case $option in
esac
done
Key Points:
Advantages:
1. basename:
● Strips the directory path and returns only the filename. You can also remove
a file extension if specified.
● Example: basename /home/user/file.txt → file.txt, and
basename /home/user/file.txt .txt → file.
2. dirname:
3. realpath:
Examples:
if [ -d /home/user/Documents ]; then echo "Directory
exists."; fi
Examples:
echo $RANDOM # Generates a random number
These commands are essential tools for file path manipulation, file existence
checking, and working with system information in Bash scripts. Let me know if
you'd like further clarification or examples!
To continue running even after the terminal is closed, you can use nohup (short
for "no hang up"). This command is useful for running long-running processes or
scripts in the background, even if the terminal session is closed or disconnected.
❖ How to Use nohup:
To run a script in the background and keep it running after closing the
terminal, use the nohup command followed by the script or command and
an & to run it in the background.
Example:
nohup bash myscript.sh &
This will run myscript.sh in the background, and the terminal can be closed
without interrupting the execution of the script. The standard output will be
redirected to a file called nohup.out unless you specify a different file.
❖ Redirecting Output:
If you don't want to see the output in the nohup.out file, you can redirect it
to /dev/null.
Alternatively, you can bring the background job to the foreground using fg
and then stop it with Ctrl + C:
fg %1 # Bring job 1 to the foreground
Summary:
● nohup is used to run a command or script that will continue executing even
after the terminal is closed.
● The & operator runs the command in the background.
● You can redirect output to a file or /dev/null to suppress output.
● Use jobs and ps to check the status of background jobs.
Steps:
1. Create a new file for the script: Open a terminal and create a new file
named calculator.sh using a text editor.
vi calculator.sh
2. Add the script code: Below is the code for the calculator:
#!/bin/bash
# Function to add two numbers
add() {
echo "Result: $(($1 + $2))"
}
case $choice in
1)
add $num1 $num2
;;
2)
subtract $num1 $num2
;;
3)
multiply $num1 $num2
;;
4)
divide $num1 $num2
;;
*)
echo "Invalid choice"
;;
esac
3. Make the script executable: After saving the script, make it executable by
running:
chmod +x calculator.sh
4. Run the script: Now you can run the calculator script using:
./calculator.sh
Example Output:
$ ./calculator.sh
Simple Calculator
Choose operation:
1. Add
2. Subtract
3. Multiply
4. Divide
Result: 15
This small project helps you understand basic conditional statements, user input
handling, and mathematical operations in Bash. You can expand this project by
adding more advanced operations (like square roots, exponents, etc.) or even a
loop to make the calculator run repeatedly.
**************************************************************************************