Master Shell Scripting: Core Commands, Variables, Loops, and Functions Explained
This comprehensive guide walks you through the fundamentals of Linux shell scripting, covering why it matters, essential prerequisites, variable handling, string manipulation, arithmetic operations, condition testing, control structures like if/else, for/while loops, functions, case statements, and array usage, all with clear examples and practical code snippets.
Shell Script Introduction
In the digital era, Linux is the preferred OS for developers and system administrators due to its efficiency, stability, and open‑source nature. Shell scripting bridges users and the system kernel, enabling flexible command execution and automation.
Why Learn Shell Programming
Shell scripts are essential for Linux/UNIX system management and automation. Every competent Linux sysadmin or DevOps engineer should master writing and reading shell scripts to improve efficiency, handle complex tasks, and advance their career.
Prerequisites for Learning Shell
Proficiency with the vim editor and SSH terminal.
Familiarity with at least 80 common Linux commands.
Understanding of Linux regular expressions and the three "grep, sed, awk" utilities.
How to Study Shell Effectively
Practice repeatedly: write, test, and refine scripts.
Reflect on each exercise: think, then code.
Iterate and repeat to build deep understanding.
Shell Basics
What Is a Shell Variable?
A shell variable stores a string; the shell does not interpret its type. For arithmetic, you must use commands like let, expr, or double parentheses.
Local variables are visible only in the current shell.
Environment variables are inherited by child processes.
Variable names must start with a letter or underscore, followed by letters, digits, or underscores. They are case‑sensitive; environment variables are conventionally uppercase. No spaces around the equals sign when assigning.
Variable Operations
Delete a variable: unset var Make a variable read‑only:
readonly varVariable Expansion
You can reference variables in many ways to obtain their value, length, substrings, or perform replacements.
Substring Extraction
name="1234567"
# Extract two characters starting at position 2
echo ${name:2:2} # 34Length of a Variable
name="1234567"
# Four ways to get length
echo $name | wc -L
expr length "$name"
awk '{print length}' <<< "$name"
echo ${#name}Pattern Deletion
url="www.baidu.com"
# Remove prefix greedily
echo ${url#www.} # baidu.com
# Remove suffix
echo ${url%.*} # www.baiduPattern Replacement
url="www.baidu.com"
# Replace first occurrence
echo ${url/w/W} # Www.baidu.com
# Replace all occurrences
echo ${url//w/W} # WWW.baidu.comArithmetic in Shell
Using expr
expr 1 + 1 # 2
expr 10 - 5 # 5
expr 10 \* 2 # 20Using Double Parentheses
echo $((10 + 5)) # 15Using $[]
echo $[10 * 5] # 50Using let
let a=5+3
echo $a # 8Using bc for Decimal Arithmetic
echo "10.5 + 2.3" | bc # 12.8Using awk for Arithmetic
awk 'BEGIN{print 10.5+2.3}' # 12.8Control Structures
If Statements
# Single branch
if [ -f /etc/hosts ]; then
echo "File exists"
fi
# Two branches
if [ -f /etc/hosts ]; then
echo "Exists"
else
echo "Missing"
fi
# Multiple branches
if [ $num -gt $max ]; then
echo "Greater"
elif [ $num -lt $max ]; then
echo "Less"
else
echo "Equal"
fiCase Statement
case $1 in
Shell) echo "Shell..." ;;
MySQL) echo "MySQL..." ;;
Docker) echo "Docker..." ;;
*) echo "Usage: $0 [Shell|MySQL|Docker]" ;;
esacFor Loop
# Iterate over a list
for i in 1 2 3; do
echo $i
done
# Iterate over a range
for i in {1..5}; do
echo $i
doneWhile Loop
# Infinite loop
while true; do
echo "Running"
sleep 1
done
# Read file line by line
while read line; do
echo $line
done < /etc/hostsFunctions
# Define a function
my_func() {
echo "Function body"
}
# Call the function
my_funcFunctions can accept positional parameters ( $1, $2, …) and return a status with return. Use local to create variables scoped to the function.
Arrays
Indexed (Numeric) Arrays
# Declare and assign
array[0]=shell
array[1]=mysql
array[2]=docker
# Access elements
echo ${array[1]} # mysql
# All values
echo ${array[@]} # shell mysql docker
# All indices
echo ${!array[@]} # 0 1 2Associative Arrays
# Declare associative array
declare -A colors
colors[red]="#FF0000"
colors[green]="#00FF00"
# Access
echo ${colors[red]} # #FF0000
# Iterate
for key in "${!colors[@]}"; do
echo "$key => ${colors[$key]}"
donePractical Examples
YUM Repository Switch Based on OS Version
#!/bin/sh
backup="mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup"
os_version=$(cat /etc/redhat-release | awk '{print $(NF-1)}')
if [ ${os_version%%.*} -eq 7 ]; then
$backup
yum -y install wget
wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
elif [ ${os_version%%.*} -eq 6 ]; then
$backup
wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-6.repo
fiInteractive Menu for System Info
#!/bin/sh
menu(){
cat <<EOF
1) Show memory (f)
2) Show load (w)
3) Show disk (d)
4) Show login info (l)
5) Show menu (m)
6) Exit (e)
EOF
}
menu
while true; do
read -p "Choose option: " opt
case $opt in
1|f) free -h ;;
2|w) uptime ;;
3|d) df -h ;;
4|l) last ;;
5|m) menu ;;
6|e) exit ;;
*) echo "Invalid option" ;;
esac
doneJump Server Menu
#!/bin/sh
web01=10.0.0.7
web02=10.0.0.8
menu(){
cat <<EOF
1) web01 $web01
2) web02 $web02
3) Exit
EOF
}
menu
while true; do
read -p "Select server: " sel
case $sel in
1|web01) ssh root@$web01 ;;
2|web02) ssh root@$web02 ;;
3|exit) exit ;;
*) echo "Invalid" ;;
esac
doneLinux Cloud Computing Practice
Welcome to Linux Cloud Computing Practice. We offer high-quality articles on Linux, cloud computing, DevOps, networking and related topics. Dive in and start your Linux cloud computing journey!
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
