Operations 23 min read

Master Shell Scripting: From Basics to Real‑World Automation

This comprehensive guide introduces shell fundamentals, explains common shells, scripting conventions, variables, control structures, loops, functions, arrays, and provides practical scripts for tasks like backups, system monitoring, and LNMP deployment, all illustrated with clear Bash examples.

Liangxu Linux
Liangxu Linux
Liangxu Linux
Master Shell Scripting: From Basics to Real‑World Automation

1. Introduction to Shell

The article begins by defining a shell as a command interpreter that bridges the user and the operating system, emphasizing that a shell script is simply a sequence of Linux commands combined to achieve a specific goal. It lists the most common shells, such as Bourne Shell (/bin/sh), Bash (/bin/bash), C Shell (/bin/csh), K Shell (/bin/ksh), and the root shell (/sbin/sh), noting that Bash is the default on most Linux distributions.

2. Shell Scripting Best Practices

Script filenames should use English letters, numbers, and underscores, end with .sh, and avoid spaces or special symbols.

Every script should start with a shebang line, typically #!/bin/bash.

Variable names must begin with a letter or underscore; they cannot start with a digit or contain hyphens.

3. Your First Script – Hello World

# Create the script file
touch HelloWorld.sh
# Edit the file (e.g., with vim)
vim HelloWorld.sh
# Inside HelloWorld.sh
#!/bin/bash
# This is our first shell script
echo "hello world"
# Make it executable
chmod +x HelloWorld.sh
# Run it
./HelloWorld.sh

The script prints hello world to the console.

4. Environment Variables

4.1 Types of Variables

Three categories are covered:

System variables (e.g., $0, $1$9, $*, $#, $?, $$) used for script arguments and status.

Environment variables such as PATH, HOME, SHELL, USER, PWD, TERM, HOSTNAME, PS1, HISTSIZE, RANDOM.

User variables defined by the script author (e.g., a=rivers, Httpd_sort=httpd-2.4.6-97.tar).

4.2 Using Variables

# Simple variable assignment and usage
a=18
echo $a   # prints 18

5. Conditional Statements

5.1 Basic if Syntax

# Single‑branch
if [ condition ]; then
    command1
fi

# Double‑branch
if [ condition ]; then
    command1
else
    command2
fi

# Multi‑branch
if [ condition ]; then
    command1
elif [ other ]; then
    command2
else
    command3
fi

5.2 Common Test Operators

-f

– file exists -d – directory exists -eq, -ne, -lt, -gt, -le, -ge – integer comparisons -z – empty string -x – executable || – logical OR, && – logical AND

5.3 Example: Check if crond Is Running

#!/bin/bash
name=crond
num=$(ps -ef | grep $name | grep -v grep | wc -l)
if [ $num -eq 1 ]; then
    echo "$num running!"
else
    echo "$num is not running!"
fi

5.4 Example: Verify Directory Existence

#!/bin/bash
if [ ! -d /data/rivers -a ! -d /tmp/rivers ]; then
    mkdir -p /data/rivers
fi

5.5 Example: Grade Evaluation

#!/bin/bash
grade=$1
if [ $grade -gt 90 ]; then
    echo "Very good!"
elif [ $grade -gt 70 ]; then
    echo "Good!"
elif [ $grade -ge 60 ]; then
    echo "Pass"
else
    echo "Fail"
fi

6. Loops

6.1 for Loop

for i in {1..5}; do
    echo $i
    # other commands
    done

6.2 Example: Ping a Range of Hosts

#!/bin/bash
Network=$1
for Host in $(seq 1 254); do
    ping -c 1 $Network.$Host > /dev/null && result=0 || result=1
    if [ "$result" == 0 ]; then
        echo -e "\033[32;1m$Network.$Host is up\033[0m"
        echo "$Network.$Host" >> /tmp/up.txt
    else
        echo -e "\033[31m$Network.$Host is down\033[0m"
        echo "$Network.$Host" >> /tmp/down.txt
    fi
done

6.3 while Loop

# Print numbers 1‑100
i=0
while ((i<=100)); do
    echo $i
    i=$((i+1))
    done

6.4 break and continue

# Break example
while true; do
    let N++
    if [ $N -eq 5 ]; then break; fi
    echo $N
done
# Continue example
N=0
while [ $N -lt 5 ]; do
    let N++
    if [ $N -eq 3 ]; then continue; fi
    echo $N
done

6.5 case Statement

case $option in
    start) echo "Start service";;
    stop)  echo "Stop service";;
    restart) echo "Restart service";;
    *) echo "Invalid option";;
    esac

6.6 select Menu

PS3="Select a number: "
select choice in http php mysql quit; do
    case $choice in
        http) echo "Test Httpd";;
        php)  echo "Test PHP";;
        mysql) echo "Test MySQL";;
        quit) exit;;
        *) echo "Invalid input";;
    esac
done

7. Functions and Arrays

7.1 Defining and Calling Functions

#!/bin/bash
func() {
    VAR=$((1+1))
    echo "This is a function."
    return $VAR
}
func
 echo $?

7.2 Working with Arrays

# Method 1: Initialize
IP=(10.0.0.1 10.0.0.2 10.0.0.3)
for i in "${IP[@]}"; do echo $i; done

# Method 2: Index‑based loop
for ((i=0;i<${#IP[@]};i++)); do echo ${IP[$i]}; done

8. Real‑World Scripts

8.1 Full & Incremental Backup Script

#!/bin/bash
SOURCE_DIR=($*)
TARGET_DIR=/data/backup
YEAR=$(date +%Y)
MONTH=$(date +%m)
DAY=$(date +%d)
WEEK=$(date +%u)
A_NAME=$(date +%H%M)
FILES=system_backup.tgz
CODE=$?

# Ensure target directory exists
if [ ! -d $TARGET_DIR/$YEAR/$MONTH/$DAY ]; then
    mkdir -p $TARGET_DIR/$YEAR/$MONTH/$DAY
    echo "Created $TARGET_DIR/$YEAR/$MONTH/$DAY"
fi

Full_Backup() {
    if [ "$WEEK" -eq 7 ]; then
        rm -rf $TARGET_DIR/snapshot
        cd $TARGET_DIR/$YEAR/$MONTH/$DAY
        tar -g $TARGET_DIR/snapshot -czvf $FILES "${SOURCE_DIR[@]}"
        [ "$CODE" == "0" ] && echo "Full backup succeeded"
    fi
}

Add_Backup() {
    if [ "$WEEK" -ne 7 ]; then
        cd $TARGET_DIR/$YEAR/$MONTH/$DAY
        tar -g $TARGET_DIR/snapshot -czvf ${A_NAME}$FILES "${SOURCE_DIR[@]}"
        [ "$CODE" == "0" ] && echo "Incremental backup succeeded"
    fi
}

sleep 3
Full_Backup
Add_Backup

8.2 System Information Collection

#!/bin/bash
ip_info=$(ifconfig | grep Bcast | tail -1 | awk '{print $2}' | cut -d: -f2)
cpu_info1=$(cat /proc/cpuinfo | grep 'model name' | tail -1 | awk -F: '{print $2}' | sed 's/^ //')
cpu_info2=$(cat /proc/cpuinfo | grep 'physical id' | sort | uniq -c | wc -l)
serv_info=$(hostname)
# ... other info gathering commands omitted for brevity ...

echo "IPADDR: $ip_info"
echo "HOSTNAME: $serv_info"
echo "CPU: $cpu_info1 X $cpu_info2"
# Prompt to store into MySQL (logic kept, but no marketing tone)
read -p "Write data to database? (y/n) " ensure
if [[ "$ensure" =~ ^[Yy]$ ]]; then
    mysql -uroot -p123456 -D audit -e "INSERT INTO audit_system VALUES('', '$ip_info', '$serv_info', '$cpu_info1 X $cpu_info2', ... );"
else
    echo "Skipping database write"
fi

8.3 One‑Click LNMP Deployment

#!/bin/bash
# Variables for source URLs and installation prefixes are defined for Nginx, MySQL, and PHP.
# Each component has a dedicated function (nginx_install, mysql_install, php_install) that
# downloads, extracts, configures, compiles, and installs the software. The script uses a
# <code>select</code> menu to let the user choose which component to install or to quit.

PS3="Please enter your selection: "
select i in nginx mysql php quit; do
    case $i in
        nginx) nginx_install 1;;
        mysql) mysql_install 2;;
        php)   php_install 3;;
        quit)  exit;;
        *) echo "Invalid choice";;
    esac
done

The collection of examples demonstrates how to build reusable, maintainable Bash scripts for everyday system‑administration tasks.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

BashShell scriptinglinux automationbackup scripts
Liangxu Linux
Written by

Liangxu Linux

Liangxu, a self‑taught IT professional now working as a Linux development engineer at a Fortune 500 multinational, shares extensive Linux knowledge—fundamentals, applications, tools, plus Git, databases, Raspberry Pi, etc. (Reply “Linux” to receive essential resources.)

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.