Mastering Shell Scripting: A Comprehensive Guide

Shell scripting is a powerful tool for automating tasks and managing system operations. This guide will walk you through the essentials, from basics to advanced concepts, providing examples along the way.

1. Introduction to Shell Scripts

A shell script is a text file containing a series of commands that are executed by the shell. Let’s start with the simplest script:

#!/bin/bash
echo "Hello, World!"

Save this as hello.sh and run it with bash hello.sh or make it executable with chmod +x hello.sh and run with ./hello.sh.

2. Variables

Variables store data for later use in your scripts.

Declaring and Using Variables

#!/bin/bash

# Assigning values to variables
name="Alice"
age=30
PI=3.14159

# Using variables
echo "Name: $name"
echo "Age: $age"
echo "PI: $PI"

# Command substitution
current_date=$(date +"%Y-%m-%d")
echo "Today is $current_date"

# Arithmetic operations
x=5
y=3
sum=$((x + y))
echo "Sum of $x and $y is $sum"

Variable Types

  1. String variables: name="Alice"
  2. Integer variables: age=30
  3. Floating-point variables (handled as strings): PI=3.14159
  4. Array variables: fruits=("apple" "banana" "cherry")

Special Variables

  • $0: Script name
  • $1, $2, …: Command-line arguments
  • $#: Number of arguments
  • $@: All arguments as separate words
  • $?: Exit status of the last command

3. User Input

Interact with users using the read command:

#!/bin/bash
echo "What's your name?"
read user_name
echo "Hello, $user_name!"

4. Conditional Statements

Conditional statements allow scripts to make decisions based on certain conditions.

If-Else Statement

#!/bin/bash

age=18

if [ $age -ge 18 ]; then
    echo "You are an adult."
elif [ $age -ge 13 ]; then
    echo "You are a teenager."
else
    echo "You are a child."
fi

Case Statement

#!/bin/bash

fruit="apple"

case $fruit in
    "apple")
        echo "It's an apple."
        ;;
    "banana")
        echo "It's a banana."
        ;;
    "cherry")
        echo "It's a cherry."
        ;;
    *)
        echo "Unknown fruit."
        ;;
esac

Comparison Operators

  • -eq: Equal to
  • -ne: Not equal to
  • -lt: Less than
  • -le: Less than or equal to
  • -gt: Greater than
  • -ge: Greater than or equal to

For string comparisons:

  • ==: Equal to
  • !=: Not equal to

5. Loops

Loops allow you to repeat a set of commands multiple times.

For Loop

#!/bin/bash

# Simple for loop
for i in {1..5}; do
    echo "Iteration $i"
done

# Looping through an array
fruits=("apple" "banana" "cherry")
for fruit in "${fruits[@]}"; do
    echo "I like $fruit"
done

# C-style for loop
for ((i=0; i<5; i++)); do
    echo "Count: $i"
done

While Loop

#!/bin/bash

# Simple while loop
count=0
while [ $count -lt 5 ]; do
    echo "Count: $count"
    count=$((count + 1))
done

# Reading file line by line
while IFS= read -r line; do
    echo "Line: $line"
done < "example.txt"

Until Loop

The until loop runs until a condition becomes true.

#!/bin/bash

num=1
until [ $num -gt 5 ]; do
    echo "Number: $num"
    num=$((num + 1))
done

Loop Control

  • break: Exit the loop immediately
  • continue: Skip the rest of the current iteration and continue with the next
#!/bin/bash

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 "Number: $i"
done

6. Functions

Organize your code with functions:

#!/bin/bash
greet() {
    echo "Hello, $1!"
}

greet "World"
greet "Alice"

7. Command Substitution

Use the output of commands in your script:

#!/bin/bash
current_date=$(date +"%Y-%m-%d")
echo "Today's date is $current_date"

8. File Operations

Work with files and directories:

#!/bin/bash
# Check if a file exists
if [ -f "example.txt" ]; then
    echo "File exists"
else
    echo "File does not exist"
fi

# Read file contents
while IFS= read -r line; do
    echo "$line"
done < "example.txt"

9. Error Handling

Handle errors gracefully:

#!/bin/bash
# Exit on error
set -e

# Custom error function
error_exit() {
    echo "Error: $1" >&2
    exit 1
}

# Usage
command_that_might_fail || error_exit "Command failed"

10. Advanced Example: System Information Script

Let’s combine multiple concepts into a useful script:

#!/bin/bash

print_system_info() {
    echo "System Information:"
    echo "-------------------"
    echo "Hostname: $(hostname)"
    echo "OS: $(uname -s)"
    echo "Kernel Version: $(uname -r)"
    echo "Uptime: $(uptime -p)"
    echo "CPU: $(lscpu | grep 'Model name' | cut -f 2 -d ":")"
    echo "Memory: $(free -h | awk '/^Mem:/ {print $2}')"
    echo "Disk Usage: $(df -h / | awk 'NR==2 {print $5}')"
}

print_system_info > system_info.txt

echo "System information has been saved to system_info.txt"

This script gathers various system details and saves them to a file.

Conclusion

Shell scripting is a versatile skill that can significantly enhance your productivity. Start with simple scripts and gradually build up to more complex ones. Remember, practice is key to mastering shell scripting!

Key points to remember:

  1. Always start your scripts with a shebang (#!/bin/bash).
  2. Use meaningful variable names.
  3. Comment your code for better readability.
  4. Test your scripts thoroughly, especially when dealing with system operations.
  5. Use functions to make your code modular and reusable.
  6. Leverage built-in shell commands and utilities for efficient scripting.
  7. Always consider error handling to make your scripts robust.

As you progress, explore more advanced topics like process management, signal handling, and networking in shell scripts. Happy scripting!