12. Shell Scripting Basics
12.1 Your First Script
bash
#!/bin/bash
# This is my first Shell script
# Filename: hello.sh
echo "Hello, Linux World!"
echo "Current time: $(date)"
echo "Current user: $(whoami)"
echo "Hostname: $(hostname)"bash
# Add execute permission and run the script
chmod +x hello.sh
./hello.shbash
$ ./hello.sh
Hello, Linux World!
Current time: Sat Jun 20 10:30:00 CST 2026
Current user: user
Hostname: myserver12.2 Variables
bash
#!/bin/bash
# Variable examples
# Define variables (no spaces around the equals sign!)
NAME="Linux"
VERSION=6.5
TODAY=$(date +%Y-%m-%d)
# Use variables
echo "System: $NAME"
echo "Version: ${VERSION}" # Curly braces are optional, used to disambiguate
echo "Date: $TODAY"
# Read-only variable
readonly PI=3.14159
# Delete a variable (read-only variables cannot be deleted)
unset NAME
# Special variables
echo "Script name: $0"
echo "Number of arguments: $#"
echo "All arguments: $@"
echo "Exit status of last command: $?"
echo "Current process PID: $$"
# String operations
STR="Hello World"
echo "Length: ${#STR}" # 11
echo "Substring: ${STR:0:5}" # Hello
echo "Replace: ${STR/World/Linux}" # Hello Linux12.3 Conditional Statements
bash
#!/bin/bash
# Conditional statement examples
# if-elif-else
AGE=25
if [ $AGE -lt 18 ]; then
echo "Minor"
elif [ $AGE -ge 18 ] && [ $AGE -lt 60 ]; then
echo "Adult"
else
echo "Senior"
fi
# File tests
FILE="/etc/passwd"
if [ -f "$FILE" ]; then
echo "$FILE is a regular file"
fi
if [ -d "/home/user" ]; then
echo "Home directory exists"
fi
if [ -r "$FILE" ]; then
echo "File is readable"
fi
if [ -x "/bin/ls" ]; then
echo "ls command is executable"
fi
# String comparison
STR="hello"
if [ "$STR" = "hello" ]; then
echo "Strings are equal"
fi
if [ -z "$EMPTY" ]; then
echo "Variable is empty"
fi
# More modern syntax (double brackets)
if [[ "$STR" == h* ]]; then
echo "Starts with h"
fi
# case statement
case "$1" in
start)
echo "Starting service"
;;
stop)
echo "Stopping service"
;;
restart)
echo "Restarting service"
;;
*)
echo "Usage: $0 {start|stop|restart}"
exit 1
;;
esac12.4 Loops
bash
#!/bin/bash
# Loop examples
# for loop — list form
for color in red green blue; do
echo "Color: $color"
done
# for loop — C-style
for ((i=1; i<=5; i++)); do
echo "Number: $i"
done
# for loop — iterate over files
for file in /var/log/*.log; do
echo "Log file: $file"
done
# while loop
COUNT=1
while [ $COUNT -le 5 ]; do
echo "Count: $COUNT"
((COUNT++))
done
# while reading each line of a file
while IFS= read -r line; do
echo "Line content: $line"
done < /etc/hostname
# until loop (executes while condition is false)
NUM=10
until [ $NUM -le 0 ]; do
echo -n "$NUM "
((NUM--))
done
echo ""
# break and continue
for i in {1..10}; do
if [ $i -eq 5 ]; then
continue # Skip 5
fi
if [ $i -eq 8 ]; then
break # Stop at 8
fi
echo $i
donebash
$ ./loops.sh
Color: red
Color: green
Color: blue
Number: 1
Number: 2
Number: 3
Number: 4
Number: 5
Count: 1
Count: 2
Count: 3
Count: 4
Count: 5
10 9 8 7 6 5 4 3 2 1
1
2
3
4
6
712.5 Functions
bash
#!/bin/bash
# Function examples
# Define a function
greet() {
local name=$1 # local declares a local variable
local time=$(date +%H)
if [ $time -lt 12 ]; then
echo "Good morning, $name!"
elif [ $time -lt 18 ]; then
echo "Good afternoon, $name!"
else
echo "Good evening, $name!"
fi
return 0
}
# Call the function
greet "Alice"
greet "Bob"
# Function with return value
add() {
local sum=$(( $1 + $2 ))
echo $sum # Return result via echo
}
result=$(add 3 5)
echo "3 + 5 = $result"
# Utility function: check if a command exists
check_command() {
if ! command -v "$1" &> /dev/null; then
echo "Error: $1 is not installed"
return 1
else
echo "✓ $1 is installed: $(which $1)"
return 0
fi
}
check_command git
check_command docker
check_command nonexistent_cmdbash
$ ./functions.sh
Good afternoon, Alice!
Good afternoon, Bob!
3 + 5 = 8
✓ git is installed: /usr/bin/git
✓ docker is installed: /usr/bin/docker
Error: nonexistent_cmd is not installed12.6 Practical Script: System Information Report
bash
#!/bin/bash
# sysinfo.sh — System information report script
echo "========================================="
echo " System Info Report - $(date)"
echo "========================================="
echo ""
echo "--- Host Information ---"
echo "Hostname: $(hostname)"
echo "Kernel version: $(uname -r)"
echo "Operating system: $(cat /etc/os-release | grep PRETTY_NAME | cut -d'"' -f2)"
echo "Uptime: $(uptime -p)"
echo ""
echo "--- CPU Information ---"
echo "Model: $(grep 'model name' /proc/cpuinfo | head -1 | cut -d: -f2 | xargs)"
echo "Cores: $(nproc)"
echo "Load: $(cat /proc/loadavg | awk '{print $1, $2, $3}')"
echo ""
echo "--- Memory Usage ---"
free -h | grep -v Swap
echo ""
echo "--- Disk Usage ---"
df -hT | grep -v tmpfs | grep -v devtmpfs
echo ""
echo "--- Network Interfaces ---"
ip -4 addr show | grep inet | grep -v 127.0.0.1 | awk '{print $2, $NF}'
echo ""
echo "--- Top 5 Processes (Memory) ---"
ps aux --sort=-%mem | awk 'NR<=6 {printf "%-10s %-8s %-6s %s\n", $1, $3"%", $4"%", $11}'
echo ""
echo "========================================="
echo " Report generation complete"
echo "========================================="bash
$ chmod +x sysinfo.sh && ./sysinfo.sh
-----------------------------------------
System Info Report - Sat Jun 20 10:30:00 CST 2026
-----------------------------------------
--- Host Information ---
Hostname: myserver
Kernel version: 5.15.0-91-generic
Operating system: Ubuntu 22.04.3 LTS
Uptime: up 15 hours, 23 minutes
--- CPU Information ---
Model: Intel(R) Core(TM) i7-12700H
Cores: 8
Load: 0.52 0.48 0.35
--- Memory Usage ---
total used free shared buff/cache available
Mem: 3.8Gi 2.7Gi 156Mi 128Mi 999Mi
--- Disk Usage ---
Filesystem Type Size Used Avail Use% Mounted on
/dev/sda1 ext4 50G 22G 26G 46% /
/dev/sda2 ext4 200G 156G 34G 83% /home
--- Network Interfaces ---
192.168.1.100/24 eth0
--- Top 5 Processes (Memory) ---
root 2.3% 12.5% /usr/sbin/mysqld
www-data 0.5% 8.2% apache2
root 0.1% 3.1% /usr/bin/dockerd
user 1.2% 2.8% vim
-----------------------------------------
Report generation complete
-----------------------------------------