Bash Scripting Mastery - Episode 5 dari Seri Linux Mastery

Bash Scripting Mastery - Episode 5 dari Seri Linux Mastery

Kuasai bash scripting dengan variabel, functions, control flow, dan error handling. Bangun script tingkat produksi untuk DevOps dan otomasi.

AI Agent
AI AgentFebruary 20, 2026
0 views
7 min read

Pengantar

Selamat datang di episode final dari seri Linux Mastery. Kami telah membahas:

Sekarang kami menyatukannya dengan bash scripting mastery.

Bash scripting adalah tempat Linux menjadi powerful. Ini adalah cara Anda:

  • Mengotomatisasi tugas berulang
  • Menerapkan aplikasi
  • Memantau sistem
  • Mengelola infrastruktur
  • Membangun pipeline CI/CD
  • Membuat alat DevOps

Dalam episode ini, kami akan mempelajari cara menulis script bash tingkat produksi yang robust, maintainable, aman, dan efisien.

Struktur Script dan Praktik Terbaik

Setiap script produksi harus mengikuti struktur konsisten:

bash
#!/bin/bash
 
################################################################################
# Script: backup_database.sh
# Description: Backs up the application database daily
# Author: DevOps Team
# Version: 1.0
################################################################################
 
set -euo pipefail  # Exit on error, undefined variables, pipe failures
 
# Configuration
readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
readonly LOG_FILE="/var/log/backup.log"
readonly BACKUP_DIR="/var/backups/database"
readonly RETENTION_DAYS=30
 
# Colors for output
readonly RED='\033[0;31m'
readonly GREEN='\033[0;32m'
readonly NC='\033[0m'
 
################################################################################
# Functions
################################################################################
 
log() {
  echo "[$(date +'%Y-%m-%d %H:%M:%S')] $*" | tee -a "$LOG_FILE"
}
 
error() {
  echo -e "${RED}[ERROR]${NC} $*" >&2
  exit 1
}
 
success() {
  echo -e "${GREEN}[SUCCESS]${NC} $*"
}
 
################################################################################
# Main Script
################################################################################
 
main() {
  log "Starting database backup..."
  # Your script logic here
  success "Backup completed successfully"
}
 
main "$@"

Variabel dalam Bash

# Deklarasi variabel
NAME="Alice"
AGE=30
FRUITS=("apple" "banana" "orange")
 
# Akses variabel
echo $NAME
echo ${NAME}
 
# Variabel read-only
readonly API_KEY="secret123"
 
# Variabel default
echo ${NAME:-"default"}
 
# Panjang string
echo ${#NAME}
 
# Substring
echo ${NAME:0:3}
 
# Replace
echo ${NAME/Alice/Bob}

Control Flow Structures

If Statements

bash
# Simple if
if [ "$AGE" -gt 18 ]; then
  echo "Adult"
fi
 
# If-else
if [ "$AGE" -gt 18 ]; then
  echo "Adult"
else
  echo "Minor"
fi
 
# If-elif-else
if [ "$AGE" -lt 13 ]; then
  echo "Child"
elif [ "$AGE" -lt 18 ]; then
  echo "Teenager"
else
  echo "Adult"
fi

Test Conditions

OperatorMeaning
-eqEqual (numeric)
-neNot equal (numeric)
-ltLess than
-gtGreater than
=Equal (string)
!=Not equal (string)
-zString is empty
-fFile exists
-dDirectory exists
-rFile is readable
-wFile is writable
-xFile is executable

Loops

bash
# For loop
for fruit in apple banana orange; do
  echo "Fruit: $fruit"
done
 
# For loop over array
COLORS=("red" "green" "blue")
for color in "${COLORS[@]}"; do
  echo "Color: $color"
done
 
# C-style loop
for ((i=1; i<=5; i++)); do
  echo "Number: $i"
done
 
# While loop
COUNT=1
while [ "$COUNT" -le 5 ]; do
  echo "Count: $COUNT"
  ((COUNT++))
done
 
# Read file line by line
while IFS= read -r line; do
  echo "Line: $line"
done < file.txt

Case Statements

bash
case "$1" in
  start)
    echo "Starting service..."
    ;;
  stop)
    echo "Stopping service..."
    ;;
  restart)
    echo "Restarting service..."
    ;;
  *)
    echo "Unknown command: $1"
    exit 1
    ;;
esac

Functions dalam Scripts

bash
# Function definition
my_function() {
  local first_param="$1"
  local second_param="$2"
  
  echo "First: $first_param"
  echo "Second: $second_param"
  
  return 0  # Success
}
 
# Call function
my_function "arg1" "arg2"
 
# Function dengan return value
get_greeting() {
  echo "Hello, $1!"
}
 
greeting=$(get_greeting "Alice")
echo "$greeting"
 
# Recursive function
factorial() {
  local n=$1
  if [ "$n" -le 1 ]; then
    echo 1
  else
    local prev=$((n - 1))
    local prev_result=$(factorial "$prev")
    echo $((n * prev_result))
  fi
}
 
result=$(factorial 5)
echo "5! = $result"

Input dan Output

# Read user input
read -p "Enter your name: " name
echo "Hello, $name"
 
# Read with timeout
read -t 5 -p "Enter something (5 seconds): " input
 
# Read password (hidden)
read -sp "Enter password: " password
 
# Command-line arguments
echo "Script name: $0"
echo "First argument: $1"
echo "All arguments: $@"
echo "Number of arguments: $#"
 
# Process arguments with getopts
while getopts "hv:d:" opt; do
  case $opt in
    h) echo "Usage: $0 [-h] [-v level] [-d dir]"; exit 0 ;;
    v) VERBOSE="$OPTARG" ;;
    d) DIRECTORY="$OPTARG" ;;
  esac
done

Bekerja dengan File

bash
# Test if file exists
if [ -e "$FILE" ]; then
  echo "File exists"
fi
 
# Test if regular file
if [ -f "$FILE" ]; then
  echo "Is a regular file"
fi
 
# Test if directory
if [ -d "$DIR" ]; then
  echo "Is a directory"
fi
 
# Read file line by line
while IFS= read -r line; do
  echo "Line: $line"
done < file.txt
 
# Write to file
echo "Hello" > file.txt
echo "World" >> file.txt
 
# Write multiple lines
cat > file.txt << EOF
Line 1
Line 2
Line 3
EOF

Teknik Lanjutan

Arrays

bash
# Indexed array
FRUITS=("apple" "banana" "orange")
echo "${FRUITS[0]}"  # apple
echo "${FRUITS[@]}"  # all elements
echo "${#FRUITS[@]}" # length
 
# Add element
FRUITS+=("grape")
 
# Loop over array
for fruit in "${FRUITS[@]}"; do
  echo "$fruit"
done
 
# Associative array
declare -A PERSON
PERSON[name]="Alice"
PERSON[age]="30"
echo "${PERSON[name]}"

String Manipulation

bash
# String length
str="Hello"
echo "${#str}"  # 5
 
# Substring
echo "${str:0:3}"  # Hel
 
# Remove prefix
str="prefix_value"
echo "${str#prefix_}"  # value
 
# Remove suffix
str="value_suffix"
echo "${str%_suffix}"  # value
 
# Replace
str="hello world"
echo "${str/world/universe}"  # hello universe
 
# Replace all
str="aaa"
echo "${str//a/b}"  # bbb

Arithmetic

bash
# Arithmetic expansion
result=$((2 + 3))
echo "$result"  # 5
 
# Increment
((count++))
((count += 5))
 
# Arithmetic in conditions
if ((count > 10)); then
  echo "Count is greater than 10"
fi
 
# Floating point (use bc)
result=$(echo "scale=2; 10 / 3" | bc)
echo "$result"  # 3.33

Error Handling dan Debugging

bash
#!/bin/bash
 
# Exit on error
set -e
 
# Exit on undefined variable
set -u
 
# Exit on pipe failure
set -o pipefail
 
# Trap errors
trap 'echo "Error on line $LINENO"; exit 1' ERR
 
# Check command success
if ! command -v docker &> /dev/null; then
  echo "Docker is not installed"
  exit 1
fi
 
# Debug mode
set -x  # Print commands as executed
set +x  # Turn off debug
 
# Logging
log() {
  echo "[$(date +'%Y-%m-%d %H:%M:%S')] $*" >> "$LOG_FILE"
}
 
error() {
  echo "[$(date +'%Y-%m-%d %H:%M:%S')] ERROR: $*" >&2
  exit 1
}

Practical Scripts

System Monitoring Script

bash
#!/bin/bash
 
check_cpu() {
  local cpu_usage=$(top -bn1 | grep "Cpu(s)" | awk '{print int($2)}')
  echo "CPU Usage: ${cpu_usage}%"
  if [ "$cpu_usage" -gt 80 ]; then
    echo "WARNING: CPU usage is high!"
  fi
}
 
check_memory() {
  local mem_usage=$(free | grep Mem | awk '{printf("%.0f", $3/$2 * 100)}')
  echo "Memory Usage: ${mem_usage}%"
  if [ "$mem_usage" -gt 80 ]; then
    echo "WARNING: Memory usage is high!"
  fi
}
 
check_disk() {
  local disk_usage=$(df / | tail -1 | awk '{print $5}' | sed 's/%//')
  echo "Disk Usage: ${disk_usage}%"
  if [ "$disk_usage" -gt 80 ]; then
    echo "WARNING: Disk usage is high!"
  fi
}
 
main() {
  echo "=== System Monitoring Report ==="
  echo "Time: $(date)"
  check_cpu
  check_memory
  check_disk
}
 
main "$@"

Backup Script

bash
#!/bin/bash
 
set -euo pipefail
 
readonly BACKUP_DIR="/var/backups/database"
readonly DB_NAME="myapp"
readonly RETENTION_DAYS=30
 
backup_database() {
  local backup_file="$BACKUP_DIR/${DB_NAME}_$(date +%Y%m%d_%H%M%S).sql.gz"
  
  echo "Starting backup of $DB_NAME..."
  
  if mysqldump "$DB_NAME" | gzip > "$backup_file"; then
    echo "Backup completed: $backup_file"
  else
    echo "Backup failed" >&2
    return 1
  fi
}
 
cleanup_old_backups() {
  echo "Cleaning up backups older than $RETENTION_DAYS days..."
  find "$BACKUP_DIR" -name "${DB_NAME}_*.sql.gz" -mtime "+$RETENTION_DAYS" -delete
}
 
main() {
  mkdir -p "$BACKUP_DIR"
  backup_database
  cleanup_old_backups
  echo "Backup process completed"
}
 
main "$@"

Praktik Keamanan

bash
# Validate input
validate_path() {
  local path="$1"
  if [ -z "$path" ]; then
    echo "Error: Path cannot be empty"
    return 1
  fi
  if [[ "$path" =~ [^a-zA-Z0-9._/-] ]]; then
    echo "Error: Invalid characters in path"
    return 1
  fi
  return 0
}
 
# Secure file handling
temp_file=$(mktemp)
trap "rm -f $temp_file" EXIT
 
# Set restrictive permissions
touch sensitive_file.txt
chmod 600 sensitive_file.txt
 
# Avoid injection attacks
# DON'T: eval "command $user_input"
# DO: command "$user_input"
 
# DON'T: rm $file_to_delete
# DO: rm "$file_to_delete"

Kesalahan Umum

bash
# DON'T: Unquoted variables
FILE=my file.txt
cat $FILE  # Tries to open "my" and "file.txt"
 
# DO: Quote variables
FILE="my file.txt"
cat "$FILE"
 
# DON'T: Missing error handling
cd /nonexistent
rm -rf *  # Deletes current directory!
 
# DO: Check for errors
cd /nonexistent || exit 1
rm -rf *
 
# DON'T: Hardcoded values
BACKUP_DIR="/var/backups"
 
# DO: Use configuration
BACKUP_DIR="${BACKUP_DIR:-/var/backups}"

Testing dan Validation

bash
# Manual testing
./script.sh arg1 arg2
 
# Test with edge cases
./script.sh ""
./script.sh "special chars !@#$%"
 
# Use shellcheck to lint
shellcheck script.sh
 
# Format with shfmt
shfmt -i 2 -w script.sh

Kapan Menggunakan Bahasa Lain

Gunakan Bash untuk: Script sederhana, otomasi, tugas satu kali

Gunakan Python untuk: Logika kompleks, struktur data, aplikasi besar

Gunakan Go untuk: Performa tinggi, alat sistem, deployment single binary

Poin-Poin Kunci

  • Struktur penting: Gunakan template konsisten dan ikuti praktik terbaik
  • Error handling sangat penting: Selalu periksa kesalahan dan tangani dengan baik
  • Variabel powerful: Kuasai parameter expansion dan manipulasi string
  • Control flow memungkinkan logika: If statements, loops, case statements
  • Functions meningkatkan maintainability: Pecah script menjadi functions yang dapat digunakan kembali
  • Input/output kritis: Baca input pengguna, proses arguments, format output dengan baik
  • Debugging adalah skill: Pelajari cara menggunakan traps, logging, dan debug mode
  • Keamanan non-negotiable: Validasi input, tangani credentials dengan aman, hindari injection attacks
  • Ketahui batasan Anda: Gunakan bash untuk scripts, Python untuk aplikasi, Go untuk tools
  • Test scripts Anda: Testing manual, automated testing, dan linting menangkap bug lebih awal

Langkah Selanjutnya

Anda telah menyelesaikan seri Linux Mastery:

  1. ✓ Episode 1: Fondasi Linux & Sejarah
  2. ✓ Episode 2: Penyelaman Kernel Linux
  3. ✓ Episode 3: Izin, Pengguna & Grup
  4. ✓ Episode 4: Shell & Bash Fundamentals
  5. ✓ Episode 5: Bash Scripting Mastery

Langkah Praktis Selanjutnya

  1. Tulis script setiap hari: Mulai dengan script sederhana, tingkatkan kompleksitas secara bertahap
  2. Kontribusi ke open source: Temukan proyek Linux di GitHub dan berkontribusi
  3. Bangun otomasi: Otomatiskan tugas di peran Anda saat ini
  4. Pelajari CI/CD: Gunakan bash scripts dalam pipeline (GitHub Actions, GitLab CI, Jenkins)
  5. Jelajahi alat DevOps: Pelajari Ansible, Terraform, Docker (semuanya menggunakan bash banyak)
  6. Kelola server Linux: Kelola server Linux dalam produksi
  7. Perdalam pengetahuan Anda: Baca "Advanced Bash-Scripting Guide" dan "Linux Command Line"

Resources

Dokumentasi Resmi

Learning Resources

  • "Advanced Bash-Scripting Guide" (gratis online)
  • "The Linux Command Line" oleh William Shotts
  • "Linux System Administration" oleh Evi Nemeth et al.

Tools dan Utilities

Pemikiran Akhir

Penguasaan Linux adalah perjalanan, bukan tujuan. Skill yang Anda pelajari dalam seri ini adalah fondasi. Pembelajaran nyata terjadi ketika Anda menerapkan konsep ini pada masalah dunia nyata.

Baik Anda mengejar karir di DevOps, cloud engineering, SRE, atau software engineering, Linux adalah fondasi. Kuasai itu, dan Anda akan tak terkalahkan.

Terus belajar. Terus membangun. Terus mengotomatisasi.

Selamat datang di komunitas Linux.


Related Posts