Bash Script

Creating and executing Bash shell scripts

📜 What is a Bash Script?

A Bash script is a text file containing a series of commands that the shell executes sequentially. Scripts automate repetitive tasks, combine multiple commands, and create powerful tools for system administration and development.


#!/bin/bash
# My first script
echo "Hello, World!"
                                    

Key Script Concepts

🎯

Shebang

Specify the interpreter

#!/bin/bash
🔐

Permissions

Make scripts executable

chmod +x script.sh
▶️

Execution

Run your scripts

./script.sh
📥

Arguments

Pass data to scripts

./script.sh arg1 arg2

🔹 Creating Your First Script

To create a Bash script, save commands in a text file with a .sh extension and a shebang line. Start with #!/bin/bash to specify the interpreter. Make it executable with chmod +x script.sh and run it with ./script.sh. A simple first script might just echo "Hello, World!". This process turns a sequence of shell commands into an automated, reusable program. Always include comments to explain the script's purpose and use clear, consistent naming for files and variables to establish good habits from the start.

#!/bin/bash
# hello.sh - My first Bash script

echo "Hello, World!"
echo "Welcome to Bash scripting!"
date
echo "Current user: $USER"

Steps to create and run:

  1. Create file: nano hello.sh
  2. Write the script above
  3. Save and exit
  4. Make executable: chmod +x hello.sh
  5. Run it: ./hello.sh

Output:

Hello, World!
Welcome to Bash scripting!
Fri Jan 10 15:30:00 UTC 2025
Current user: john

🔹 Script Arguments

Scripts accept command-line arguments accessible via positional parameters: $1, $2, etc. $0 is the script's name. $@ represents all arguments, and $# gives the count. This allows users to pass inputs like filenames or options. For example, a backup script might take a source and destination: ./backup.sh /home /mnt/backup. Inside, $1 is "/home". Always validate argument count and content to ensure robust operation. Arguments make scripts flexible tools adaptable to different contexts without modifying the code.

#!/bin/bash
# greet.sh - Script with arguments

echo "Script name: $0"
echo "First argument: $1"
echo "Second argument: $2"
echo "All arguments: $@"
echo "Number of arguments: $#"
# Run the script
./greet.sh Alice Bob

Output:

Script name: ./greet.sh
First argument: Alice
Second argument: Bob
All arguments: Alice Bob
Number of arguments: 2

🔹 Conditional Statements

Conditional statements (if, case) enable scripts to make decisions and branch execution. They evaluate conditions (file existence, string matches, numeric comparisons) and run different code blocks based on the result. This introduces logic and adaptability. For example, a script can check if a directory exists before creating it or validate user input before proceeding. Mastering conditionals is fundamental to writing intelligent scripts that don't just run commands linearly but respond appropriately to the system's state and user input, handling both success and error paths gracefully.

#!/bin/bash
# check_age.sh - Conditional example

age=$1

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
# Run with different ages
./check_age.sh 25
./check_age.sh 15
./check_age.sh 10

Output:

You are an adult
You are a teenager
You are a child

🔹 Loops

Loops (for, while, until) automate repetition, processing multiple items or waiting for conditions. For loops iterate over known lists (files, numbers). While and until loops repeat based on dynamic conditions (e.g., until a process finishes). They are the engine of automation—performing the same task on hundreds of files, reading configuration lines, or monitoring system state. Loops, combined with conditionals and variables, transform simple command lists into powerful, scalable automation scripts that save time and reduce manual effort.

🔸 For Loop

#!/bin/bash
# for_loop.sh

# Loop through numbers
for i in 1 2 3 4 5
do
    echo "Number: $i"
done

# Loop through files
for file in *.txt
do
    echo "Found: $file"
done

🔸 While Loop

#!/bin/bash
# while_loop.sh

counter=1
while [ $counter -le 5 ]
do
    echo "Count: $counter"
    ((counter++))
done

Output:

Number: 1
Number: 2
Number: 3
Number: 4
Number: 5

🔹 Functions

Functions are reusable code blocks that organize logic, accept parameters, and can return values. They promote the DRY (Don't Repeat Yourself) principle, making scripts modular and easier to maintain. Instead of copying code, you define a function once and call it multiple times. Functions can encapsulate complex operations (like error logging or data validation) behind a simple name. This abstraction makes the main script cleaner and more readable. Well-designed functions are the building blocks of sophisticated, reliable, and easily debuggable shell scripts, especially in larger projects.

#!/bin/bash
# functions.sh

# Define a function
greet() {
    local name=$1
    echo "Hello, $name!"
}

# Function with return value
add_numbers() {
    local sum=$(($1 + $2))
    echo $sum
}

# Call functions
greet "Alice"
greet "Bob"

result=$(add_numbers 5 3)
echo "5 + 3 = $result"

Output:

Hello, Alice!
Hello, Bob!
5 + 3 = 8

🔹 Practical Script Example

A comprehensive backup script demonstrates integrating variables, functions, conditionals, and loops. It might include a function to log messages, checks for sufficient disk space, validation of source and target directories, and a loop to compress each file. It would use trap for cleanup on exit and provide clear user feedback. Such an example shows how abstract concepts combine to solve real problems—creating a robust, automated solution for system administration. Studying and modifying practical examples is one of the fastest ways to learn effective Bash scripting patterns.

#!/bin/bash
# backup.sh - Simple backup script

# Configuration
SOURCE_DIR="$HOME/Documents"
BACKUP_DIR="$HOME/Backups"
DATE=$(date +%Y-%m-%d_%H-%M-%S)
BACKUP_NAME="backup_$DATE.tar.gz"

# Create backup directory if it doesn't exist
if [ ! -d "$BACKUP_DIR" ]; then
    mkdir -p "$BACKUP_DIR"
    echo "Created backup directory: $BACKUP_DIR"
fi

# Create backup
echo "Starting backup..."
tar -czf "$BACKUP_DIR/$BACKUP_NAME" "$SOURCE_DIR"

# Check if backup was successful
if [ $? -eq 0 ]; then
    echo "Backup completed successfully!"
    echo "Backup saved to: $BACKUP_DIR/$BACKUP_NAME"
else
    echo "Backup failed!"
    exit 1
fi

🧠 Test Your Knowledge

What is the shebang line for a Bash script?