If you're typing the same commands over and over, you're doing it wrong. Bash scripting turns repetitive command-line tasks into automated, repeatable scripts that save hours of work. As a DevOps engineer, scripting isn't optional—it's how you work smarter, not harder. In this hands-on guide, you'll write your first scripts and learn the fundamentals that power every automation task.
1. Learning Objectives
By the end of this lesson, you will be able to:
- Create and execute your first Bash script
- Use the shebang (#!/bin/bash) correctly
- Work with variables and user input (read)
- Understand and use exit codes ($?, exit 0)
- Make scripts executable with chmod +x
- Create a practical system information script
2. Why This Matters (Real-World Scenario)
Real-world scenario: Every morning, you need to check 20 servers for disk space, memory usage, and running services. Doing this manually takes 45 minutes. With a Bash script, you write it once and run it in 5 seconds.
Another scenario: Your team deploys code 10 times per day. Each deployment requires 15 manual commands. A Bash script reduces this to one command: ./deploy.sh.
3. Core Concepts
What is a Bash Script?
A Bash script is simply a text file containing a series of commands that you would normally type in the terminal. Instead of typing them one by one, Bash runs them all sequentially.
#!/bin/bash
# This is a comment - Bash ignores this line
echo "Hello, World!"
echo "Current date: $(date)"
echo "Logged in as: $(whoami)"
The Shebang (#!/bin/bash) - THE MOST IMPORTANT LINE
The shebang (#!) tells your system which interpreter to use. Without it, your system might try to run the script with the wrong shell (or not at all).
Comments (Explaining Your Code)
#!/bin/bash
# This is a single-line comment
# Comments are for humans, not computers
echo "This runs" # You can comment after a command as well
: '
This is a multi-line comment
It can span multiple lines
Useful for longer explanations
'
Making Scripts Executable
Before you can run a script, you need to make it executable. This is a safety feature—you can't accidentally run a script.
# Create the script file
nano myscript.sh
# Make it executable
chmod +x myscript.sh
# Run it
./myscript.sh
# Run it from anywhere (add to PATH later)
# Alternative: run with bash command (doesn't need +x)
bash myscript.sh
$ chmod +x myscript.sh
$ ls -l myscript.sh
-rwxr-xr-x 1 user user 45 Jan 17 10:00 myscript.sh
$ ./myscript.sh
Hello, World!
Variables: Storing Data
#!/bin/bash
# Variables - NO spaces around = !!!
name="Alex" # String
age=30 # Number
current_date=$(date) # Command output
files_count=$(ls | wc -l) # Another command
# Using variables - use $
echo "My name is $name"
echo "I am $age years old"
echo "Today is $current_date"
echo "There are $files_count files here"
# Variable naming rules
# Valid: MY_VAR, myVar, _my_var, var123
# Invalid: 123var (can't start with number), my-var (no hyphens)
$ ./variables.sh
My name is Alex
I am 30 years old
Today is Thu Jan 17 10:00:00 UTC 2025
There are 12 files here
User Input: Making Scripts Interactive
#!/bin/bash
# Asking for user input
echo "What is your name?"
read username
echo "Hello, $username!"
# Prompt with the same line
read -p "Enter your age: " age
echo "You are $age years old"
# Silent input (for passwords)
read -sp "Enter password: " password
echo "Password received"
# Default value if user presses enter
read -p "Enter directory to backup [default: /home]: " backup_dir
backup_dir=${backup_dir:-/home}
echo "Backing up $backup_dir"
$ ./user_input.sh
What is your name?
Alex
Hello, Alex!
Enter your age: 30
You are 30 years old
Enter password:
Password received
Enter directory to backup [default: /home]:
Backing up /home
Exit Codes: Did Your Script Succeed?
Every command in Linux returns an exit code:
0 = Success
1-255 = Failure (different numbers mean different errors)
#!/bin/bash
# Exit codes and error handling
echo "This command will succeed"
ls /tmp
echo "Exit code: $?" # Should be 0
echo "This command will fail"
ls /nonexistent_directory
echo "Exit code: $?" # Should be non-zero
# Set custom exit code
if [ -f "/etc/passwd" ]; then
echo "File exists"
exit 0 # Success
else
echo "File not found"
exit 1 # Failure
fi
$ ./exit_codes.sh
This command will succeed
Exit code: 0
This command will fail
ls: cannot access '/nonexistent_directory': No such file or directory
Exit code: 2
File exists
4. Hands-on Practice Lab
Setup Your Practice Environment
mkdir ~/bash-practice
cd ~/bash-practice
touch first_script.sh second_script.sh
chmod +x *.sh
Exercise 1: System Information Script
#!/bin/bash
# system_info.sh - Display system information
echo "====================================="
echo " SYSTEM INFORMATION REPORT"
echo "====================================="
echo ""
# User info
echo "User Information:"
echo " Username: $(whoami)"
echo " Home directory: $HOME"
echo " Current shell: $SHELL"
echo ""
# System info
echo "System Information:"
echo " Hostname: $(hostname)"
echo " OS: $(uname -o)"
echo " Kernel: $(uname -r)"
echo " Architecture: $(uname -m)"
echo " Uptime: $(uptime -p)"
echo ""
# Disk usage
echo "Disk Usage:"
df -h | head -4
echo ""
# Memory usage
echo "Memory Usage:"
free -h
echo ""
# Current processes
echo "Top 5 CPU-consuming processes:"
ps aux --sort=-%cpu | head -6
echo ""
echo "Report generated on: $(date)"
Exercise 2: Interactive Backup Script
#!/bin/bash
# backup.sh - Create a timestamped backup
# Color codes for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
echo -e "${GREEN}=== Backup Utility ===${NC}"
# Get source directory
read -p "Enter directory to backup: " source_dir
# Check if source exists
if [ ! -d "$source_dir" ]; then
echo -e "${RED}Error: Directory '$source_dir' does not exist!${NC}"
exit 1
fi
# Get backup destination (default: current directory)
read -p "Enter backup destination [default: current directory]: " dest_dir
dest_dir=${dest_dir:-.}
# Create backup filename with timestamp
timestamp=$(date +"%Y%m%d_%H%M%S")
backup_name="backup_$(basename "$source_dir")_$timestamp.tar.gz"
# Perform backup
echo -e "${YELLOW}Backing up $source_dir to $dest_dir/$backup_name...${NC}"
tar -czf "$dest_dir/$backup_name" "$source_dir"
# Check if backup succeeded
if [ $? -eq 0 ]; then
echo -e "${GREEN}✓ Backup successful!${NC}"
echo "Backup saved as: $dest_dir/$backup_name"
ls -lh "$dest_dir/$backup_name"
else
echo -e "${RED}✗ Backup failed!${NC}"
exit 1
fi
5. Common Errors & Solutions
6. Summary Checklist
7. Next Steps
Next lesson: Bash Lesson 2.2: Conditionals, Loops, and Functions
You'll learn to:
- Use if/else statements for decision making
- Loop with for and while
- Create reusable functions
- Compare strings and numbers
Practice resources:
- Shell Scripting Tutorial
- ExplainShell - See what each command does
- ShellCheck - Find bugs in your scripts
Comments (0)
This is exactly what I needed! The initContainer approach solved our migration issues completely. Thanks for the detailed guide!
ReplyLeave a Comment