Table of Contents
- The Shebang Line: Start Your Script Right
- Mastering Variables: Store and Reuse Data
- Conditional Statements: Make Decisions in Scripts
- Loops: Automate Repetitive Tasks
- Functions: Reusable Code Blocks
- Error Handling: Write Robust Scripts
- Input/Output Redirection: Control Data Flow
- Cron Jobs: Schedule Automated Tasks
- Essential Tools for Automation: grep, awk, and sed
- Debugging Bash Scripts: Troubleshoot Like a Pro
- Best Practices: Security, Readability, and Scalability
- References
1. The Shebang Line: Start Your Script Right
Every Bash script should begin with a shebang line (#!), which tells the system which interpreter to use. Without it, the script may run in a different shell (e.g., sh instead of bash), leading to unexpected behavior.
Example:
#!/bin/bash
# This script will run in Bash, not sh
echo "Hello, Bash!"
Why It Matters:
#!/bin/bashensures compatibility with Bash-specific features (e.g., arrays,[[ ]]conditionals).- Avoid
#!/bin/shunless you explicitly need POSIX compliance (it may use a minimal shell likedash).
2. Mastering Variables: Store and Reuse Data
Variables let you store and manipulate data (e.g., file paths, usernames, timestamps). They make scripts dynamic and easier to maintain.
Types of Variables:
- User-defined: Created by you (e.g.,
BACKUP_DIR="/var/backups"). - Environment: Inherited from the shell (e.g.,
$HOME,$PATH). - Special: Built-in variables (e.g.,
$?for exit status,$0for script name,$1for first argument).
Example:
#!/bin/bash
# User-defined variable
GREETING="Hello"
USER="Admin"
# Use variables with $
echo "$GREETING, $USER!" # Output: Hello, Admin!
# Special variable: $1 (first argument passed to the script)
echo "Script name: $0" # Output: ./greet.sh
echo "First argument: $1" # Output: John (if run as ./greet.sh John)
Quoting Variables:
- Use double quotes (
" ") to preserve spaces and expand variables (e.g.,"$BACKUP_DIR"). - Use single quotes (
' ') to treat text literally (no expansion:'$BACKUP_DIR'outputs$BACKUP_DIR).
3. Conditional Statements: Make Decisions in Scripts
Conditionals (e.g., if-else, case) let your script respond to different scenarios (e.g., “if a log file is larger than 1GB, rotate it”).
Common Conditional Checks:
- File existence:
-f(regular file),-d(directory),-e(any file type). - Permissions:
-r(readable),-w(writable),-x(executable). - Numeric comparisons:
-eq(equal),-gt(greater than),-lt(less than). - String comparisons:
=,!=,-z(empty string).
Example 1: Check if a File Exists
#!/bin/bash
LOG_FILE="/var/log/syslog"
if [ -f "$LOG_FILE" ]; then
echo "$LOG_FILE exists. Size: $(du -h "$LOG_FILE")"
else
echo "$LOG_FILE not found!"
fi
Example 2: Case Statement (for Multiple Conditions)
#!/bin/bash
DAY=$(date +%A) # Get current day (e.g., Monday)
case $DAY in
Monday|Friday)
echo "Weekday: Time to work!"
;;
Saturday|Sunday)
echo "Weekend: Relax!"
;;
*)
echo "Midweek: Almost there!"
;;
esac
4. Loops: Automate Repetitive Tasks
Loops iterate over lists (e.g., files, command output) to perform actions repeatedly.
Types of Loops:
forLoop: Iterate over a fixed list.whileLoop: Run until a condition is false.untilLoop: Run until a condition is true.
Example 1: for Loop (Backup .conf Files)
#!/bin/bash
# Backup all .conf files in /etc to /var/backups/configs
BACKUP_DIR="/var/backups/configs"
mkdir -p "$BACKUP_DIR" # Create directory if it doesn't exist
for FILE in /etc/*.conf; do
cp "$FILE" "$BACKUP_DIR/$(basename "$FILE").$(date +%F)"
echo "Backed up: $FILE"
done
Example 2: while Loop (Read Lines from a File)
#!/bin/bash
# Read usernames from a file and create accounts
USER_LIST="/tmp/users.txt"
while IFS= read -r USER; do
if id "$USER" &>/dev/null; then
echo "User $USER already exists."
else
useradd "$USER"
echo "Created user: $USER"
fi
done < "$USER_LIST" # Input file
5. Functions: Reusable Code Blocks
Functions encapsulate logic into reusable blocks, reducing redundancy and improving readability.
Syntax:
function_name() {
# Code here
echo "Hello from $FUNCNAME" # $FUNCNAME is the function name
}
Example: Reusable Backup Function
#!/bin/bash
# Define a backup function
backup_file() {
local SRC="$1" # First argument: source file
local DST="$2" # Second argument: destination dir
local TIMESTAMP=$(date +%F_%H-%M)
if [ ! -f "$SRC" ]; then
echo "Error: $SRC not found."
return 1 # Return non-zero exit code for failure
fi
cp "$SRC" "$DST/$(basename "$SRC").$TIMESTAMP"
echo "Backup successful: $DST/$(basename "$SRC").$TIMESTAMP"
return 0 # Success
}
# Use the function
backup_file "/etc/nginx/nginx.conf" "/var/backups/nginx"
backup_file "/etc/ssh/sshd_config" "/var/backups/ssh"
6. Error Handling: Write Robust Scripts
Unchecked errors can break scripts. Use these techniques to make scripts resilient:
Key Tools:
set -e: Exit immediately if any command fails.set -u: Treat unset variables as errors.set -o pipefail: Fail if any command in a pipeline fails.trap: Run commands on script exit (e.g., clean up temporary files).
Example: Safe Script with Error Handling
#!/bin/bash
set -euo pipefail # Exit on error, unset variable, or pipeline failure
# Clean up temporary files on exit
trap 'rm -f /tmp/tempfile.txt' EXIT
# Create a temporary file
echo "Temporary data" > /tmp/tempfile.txt
# Simulate an error (script will exit here due to set -e)
false # This command fails
# This line will NEVER run
echo "This message is lost!"
7. Input/Output Redirection: Control Data Flow
Redirect output (stdout, stderr) to files or discard it, and redirect input from files.
Common Operators:
>: Overwrite file with stdout.>>: Append stdout to file.2>: Redirect stderr to file.&>: Redirect both stdout and stderr.<: Read input from file.<<EOF: Here-document (multi-line input).
Example: Logging and Discarding Errors
#!/bin/bash
# Log script output to a file, discard errors
LOG_FILE="/var/log/backup_script.log"
echo "Starting backup at $(date)" >> "$LOG_FILE"
rsync -av /home /var/backups >> "$LOG_FILE" 2>/dev/null # Discard stderr
echo "Backup completed at $(date)" >> "$LOG_FILE"
Example: Here-Document (Generate a Config File)
#!/bin/bash
# Create a custom nginx config using a here-document
cat > /etc/nginx/sites-available/myapp <<EOF
server {
listen 80;
server_name myapp.example.com;
root /var/www/myapp;
}
EOF
8. Cron Jobs: Schedule Automated Tasks
Cron is a time-based job scheduler to run scripts at specific intervals (e.g., daily backups, hourly log rotation).
Cron Syntax:
* * * * * command-to-run
| | | | |
| | | | +-- Day of week (0-6, 0=Sunday)
| | | +---- Month (1-12)
| | +------ Day of month (1-31)
| +-------- Hour (0-23)
+---------- Minute (0-59)
Example: Daily Backup at 2 AM
- Edit the crontab:
crontab -e - Add:
0 2 * * * /usr/local/bin/backup_script.sh >> /var/log/daily_backup.log 2>&10 2 * * *: Run at 2:00 AM daily.>> /var/log/...: Append logs.2>&1: Redirect stderr to stdout.
9. Essential Tools for Automation: grep, awk, and sed
Combine Bash with these tools to parse text, filter data, and edit files.
grep: Filter lines matching a pattern
# Find errors in /var/log/syslog
grep "ERROR" /var/log/syslog
awk: Process structured text (e.g., CSV, logs)
# Print disk usage for partitions over 80% (from df -h)
df -h | awk '$5 > "80%" {print "Warning: " $0}'
sed: Edit text (substitute, delete lines)
# Replace "old" with "new" in a file (in-place)
sed -i 's/old/new/g' /etc/config.ini
10. Debugging Bash Scripts: Troubleshoot Like a Pro
Use these tools to fix broken scripts:
set -x: Print commands and variables as they execute (trace mode).#!/bin/bash set -x # Enable debugging echo "Hello, $USER" set +x # Disable debuggingshellcheck: Static analysis tool to catch errors (install withapt install shellcheck).shellcheck my_script.shechoStatements: Print variable values to verify logic.
11. Best Practices: Security, Readability, and Scalability
-
Security:
- Avoid hardcoding passwords (use environment variables or
read -sfor input). - Restrict script permissions:
chmod 700 my_script.sh(only owner can execute). - Validate user input to prevent injection attacks.
- Avoid hardcoding passwords (use environment variables or
-
Readability:
- Use comments to explain why, not what.
- Use meaningful variable/function names (e.g.,
BACKUP_DIRinstead ofbd).
-
Scalability:
- Break large scripts into smaller functions or separate files.
- Use version control (Git) to track changes.
12. References
By mastering these Bash automation tips, you’ll turn tedious tasks into efficient, reliable workflows. Start small—automate one task today—and build from there. Happy scripting! 🚀