Note_Tech

All technological notes.


Project maintained by simonangel-fong Hosted on GitHub Pages — Theme by mattgraham

Linux - Shell: Script

Back


Shell Script


Key Concepts of Shell Scripting

Shebang (#!)

#!/bin/bash
# use the bash shell to interpret the script.

Basic Structure

#!/bin/bash
# comments
echo "Hello, World!"
date
ls -l

Make a Script Executable

chmod +x myscript.sh
# Using the Relative or Absolute Path
# absolute path
/absolute/path/myscript.sh

# relative path
./myscript.sh

# Using the `bash` or `sh` Command
bash /absolute/path/myscript.sh
sh /absolute/path/myscript.sh

bash ./myscript.sh
sh ./myscript.sh

# Using the Path Variable ($PATH)
mv hello.sh /usr/local/bin/
chmod +x /usr/local/bin/hello.sh
hello.sh  # execute the script without specifying its path

Common Errors and

chmod +x hello.sh
# Verify with:
which bash

Variables

#!/bin/bash
# Example of defining variables
a=Abc
b=XYZ
c="Linux class"

echo "My first name is $a"
echo "My surname is $b"
echo “My surname is $c

Single Quotes (‘) and Double Quotes (“)

touch single_quotes
chmod +x single_quotes

vi single_quotes
#!/bin/bash

VAR="Hello world"
echo 'Message: $VAR'
echo 'Message: ${VAR}'
echo 'Today is $(date)'
echo 'Today is `date`'

./single_quotes
# Message: $VAR
# Message: ${VAR}
# Today is $(date)
# Today is `date`

touch double_quotes
chmod +x double_quotes

vi double_quotes
# #!/bin/bash

# VAR="Hello world"
# echo "Message: $VAR"
# echo "Message: ${VAR}"
# echo "Today is $(date)"
# echo "Today is `date`"

./double_quotes
# Message: Hello world
# Message: Hello world
# Today is Tue Dec 17 18:43:02 EST 2024
# Today is Tue Dec 17 18:43:02 EST 2024

Parentheses () and Curly Braces {}

touch parentheses
chmod +x parentheses

vi parentheses
# #!/bin/bash

# VAR="AAAA"
# ( VAR="BBBB"; echo "Inside subshell: $VAR" )
# echo "Outside subshell: $VAR"

./parentheses
# Inside subshell: BBBB
# Outside subshell: AAAA

touch braces
chmod +x braces

vi braces
# #!/bin/bash

# VAR="AAAA"
# { VAR="BBBB"; echo "Inside braces: $VAR"; }
# echo "Outside braces: $VAR"

./braces
# Inside braces: BBBB
# Outside braces: BBBB

touch ParenthesesBraces
chmod +x ParenthesesBraces

vi ParenthesesBraces
#!/bin/bash

VAR="Hello world"
echo "Message: $(VAR)"
echo "Message: ${VAR}"
echo "Message: $(date)"
echo "Message: ${date}"

./ParenthesesBraces
# ./ParenthesesBraces: line 4: VAR: command not found
# Message:
# Message: Hello world
# Message: Tue Dec 17 19:13:59 EST 2024
# Message:

Input/Output

read: Read Input

CMD DESC
read Read into default variable REPLY
read var_name Read words into a variable
read var1 var2 Read words into multiple variables
read -s password Hides the input while typing.
read -p message -s password Display a prompt on the same line.
read -t 5 Reading with a timeout in seconds.
read -r path Prevent escape characterss
read -a array_name Reads input into an array
read -n 1 array_name Reads only a specified number of characters

read var1 var2
# input: AAA
echo $var1
# output: AAA
echo $var2
# output none

read var1 var2
# input: AAA BBB CCC
echo $var1
# output: AAA
echo $var2
# output: BBB CCC
read -p "Input login password:" -s password; echo
# Input login password:
echo $password

read -t 5 -p "Enter your name (5 seconds): " name
echo $name

read -a fruits -p "Enter three fruits:"
# input: Apple Orange Banana
echo "First: ${fruits[0]}, Second: ${fruits[1]}, Third: ${fruits[2]}"
# First: Apple, Second: Orange, Third: Banana

read -n 1 -p "Press [A] for option A. Any other key to exit:" key; echo
echo "Your key: $key"

touch read_input
chmod +x read_input

vi read_input
#!/bin/bash
echo "Enter your name:"
read NAME
echo "Hello, $NAME!"

./read_input

echo: Display message

CMD DESC
echo Display a newline
echo "A text message" Display a message
echo "Hello, $name!" Display with variable value
echo "Today is $(date)" Display with command
echo -n "This is a single line" Suppress newline
echo -e "Line 1\nLine 2\tIndented" Enable Escape Characters
echo -e "\e[31mThis is red text.\e[0m" Print colored text
echo "This is a log entry." > log.txt Overwrites the file.
echo "This is a log entry." >> log.txt Append to the end of the file
Code Color
31 Red
32 Green
33 Yellow
34 Blue
35 Magenta
36 Cyan
0m Reset (default)

ls > output.txt   # Save output to a file
cat < input.txt   # Use file content as input

Lab: Display OS information

#!/bin/bash
host=`hostname`
echo -e "Hostname: \e[32m$host\e[0m"
echo -e "Current user: \e[32m$(whoami)\e[0m"
echo -e "Current direcotry: \e[32m$(pwd)\e[0m"


Conditional Statements

[[ ]]

name="Alice"

if [[ $name == A* && $name != "Admin" ]]
then
    echo "Hello, $name!"
fi

Multiple Conditions

  1. AND Condition
if [ $num -gt 5 ] && [ $num -lt 15 ]
then
    echo "The number is between 5 and 15."
fi
  1. OR Condition
if [ $num -lt 5 ] || [ $num -gt 15 ]
then
    echo "The number is outside the range of 5 to 15."
fi

Relational Operators

Operator Description
-eq Equal to
-ne Not equal to
-gt Greater than
-ge Greater than or equal to
-lt Less than
-le Less than or equal to

String Comparison Operators

Operator Description
== Equal to
!= Not equal to
-z True if the string is empty
-n True if the string is not empty

File Test Operators

Operator Description
-e File exists
-f File is a regular file
-d File is a directory
-r File is readable
-w File is writable
-x File is executable

if-then

if [ condition ]
then
    commands
fi

If-Else

if [ condition ]
then
    commands_if_true
else
    commands_if_false
fi

elif

if [ condition1 ]
then
    commands_if_condition1_true
elif [ condition2 ]
then
    commands_if_condition2_true
else
    commands_if_all_false
fi

Loops

Break and Continue

for num in 1 2 3 4 5
do
  if [ $num -eq 3 ]
  then
    break
  fi
  echo "Number: $num"
done
# Number: 1
# Number: 2

for num in 1 2 3 4 5
do
  if [ $num -eq 3 ]
  then
    continue
  fi
  echo "Number: $num"
done
# Number: 1
# Number: 2
# Number: 4
# Number: 5

For Loop


for item in list
do
    commands
done
# Example: Iterating Over a List
for fruit in apple banana cherry
do
    echo "I like $fruit."
done
# I like apple.
# I like banana.
# I like cherry.

# Example: Iterating Over a Range of Numbers
for num in {1..5}
do
    echo "Number: $num"
done
# Number: 1
# Number: 2
# Number: 3
# Number: 4
# Number: 5

# Example: Looping Through Files
for file in *.txt
do
    echo "Processing file: $file"
done
# Processing file: a.txt
# Processing file: b.txt
# Processing file: c.txt
# Processing file: d.txt


# Example: Using Command Substitution
for user in $(cat users.txt)
do
    echo "Welcome, $user!"
done
# Welcome, AA!
# Welcome, BB!
# Welcome, CC!
# Welcome, ZZ!

for dir in $(ls /home)
do
    echo "Directory: $dir"
done
# Directory: rheladmin
# Directory: serveradmin

# Nested for Loops
for i in 1 2 3
do
    for j in A B
    do
        echo "Combination: $i$j"
    done
done
# Combination: 1A
# Combination: 1B
# Combination: 2A
# Combination: 2B
# Combination: 3A
# Combination: 3B


Lab: List all username

#!/bin/bash
i=1
for username in `awk -F: '{print $1}' /etc/passwd`
do
  echo "Username $((i++)) : $username"
done

C-Style for Loop

for (( initialization; condition; increment ))
do
    commands
done
for (( i=1; i<=5; i++ ))
do
    echo "Iteration: $i"
done
# Iteration: 1
# Iteration: 2
# Iteration: 3
# Iteration: 4
# Iteration: 5

While Loop

while [ condition ]
do
    commands
done

# Simple Counter
#!/bin/bash
count=1
while [ $count -le 5 ]
do
  echo "Count: $count"
  count=$((count + 1))
done
# Count: 1
# Count: 2
# Count: 3
# Count: 4
# Count: 5

# Infinite Loop
#!/bin/bash
while true
do
    echo "This is an infinite loop. Press Ctrl+C to stop."
    sleep 1
done

# Command Output as a Condition
#!/bin/bash
while ping -c 1 google.com > /dev/null
do
    echo "Internet is up."
    sleep 5
done
echo "Internet is down."

Functions

greet() {
  echo "Hello, $1!"
}
greet "User"

Exit Codes

mkdir test_dir
if [ $? -eq 0 ]; then
  echo "Directory created successfully."
else
  echo "Failed to create directory."
fi

Debugging

bash -x script.sh

Handle Errors Gracefully

if [ $? -ne 0 ]; then
  echo "Error occurred!"
  exit 1
fi

Shell Startup Files