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:
-
Create file:
nano hello.sh - Write the script above
- Save and exit
-
Make executable:
chmod +x hello.sh -
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