Capstone Project¶
This is where two weeks of fundamentals become a real, working tool. You will design, build, test, and document a complete shell script from scratch.
Learning Objectives¶
- Apply all Week 01 and Week 02 concepts in a single cohesive project
- Write a script with proper argument parsing, error handling, logging, and cleanup
- Test your script with edge cases: empty input, missing files, spaces in filenames
- Document your script so someone else can use it
Choose Your Project¶
Pick one of the six guided projects from the Projects section, or propose your own. The requirements are the same regardless of which you choose.
Suggested capstone for most students¶
Project 01 — System Health Monitor is recommended for the capstone because it touches every skill from both weeks: - Variables, arithmetic - Control flow and loops - Functions - Error handling and logging - cron scheduling - Output formatting
Requirements¶
Your capstone script must meet all of these:
Functionality¶
- Solves a real problem — it should be something you would actually use
- Accepts at least two command-line arguments or flags
- Has a
--help/-hflag that prints usage - Handles at least two error conditions gracefully (missing file, wrong permissions, etc.)
Code quality¶
- Starts with
#!/usr/bin/env bashandset -euo pipefail - Uses functions for repeated logic (at least 3 functions)
- Uses
localfor all function-scoped variables - Quotes every variable reference
- Passes
shellcheckwith no warnings
Robustness¶
- Works when filenames contain spaces
- Does not fail silently — every error goes to stderr with a useful message
- Includes a
trap EXITfor cleanup if the script creates temp files - Does not leave the system in a broken state if interrupted
Documentation¶
- A comment block at the top: what it does, usage, example
- The
--helpoutput is clear enough that someone unfamiliar with the script can use it
Capstone Template¶
Start from this skeleton:
#!/usr/bin/env bash
# =============================================================================
# script_name.sh — One-line description of what this does
#
# Usage:
# script_name.sh [OPTIONS] <required_arg>
#
# Options:
# -h, --help Show this help
# -v, --verbose Verbose output
# -d, --dry-run Preview without making changes
#
# Example:
# script_name.sh -v /path/to/input
# =============================================================================
set -euo pipefail
# --- config ---
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SCRIPT_NAME="$(basename "$0")"
VERBOSE=false
DRY_RUN=false
# --- cleanup ---
TMPDIR_WORK=""
cleanup() {
[[ -n "$TMPDIR_WORK" && -d "$TMPDIR_WORK" ]] && rm -rf "$TMPDIR_WORK"
}
trap cleanup EXIT
# --- logging ---
log() { echo "[$SCRIPT_NAME] $*"; }
verbose() { "$VERBOSE" && log "$*" || true; }
warn() { echo "[$SCRIPT_NAME] WARN: $*" >&2; }
die() { echo "[$SCRIPT_NAME] ERROR: $*" >&2; exit 1; }
# --- usage ---
usage() {
cat << EOF
Usage: $SCRIPT_NAME [OPTIONS] <required_arg>
Description of what the script does.
Options:
-h, --help Show this help
-v, --verbose Verbose output
-d, --dry-run Preview without changes
EOF
}
# --- arg parsing ---
parse_args() {
while [[ $# -gt 0 ]]; do
case "$1" in
-h|--help) usage; exit 0 ;;
-v|--verbose) VERBOSE=true; shift ;;
-d|--dry-run) DRY_RUN=true; shift ;;
--) shift; break ;;
-*) die "Unknown option: $1" ;;
*) break ;;
esac
done
[[ $# -ge 1 ]] || die "Required argument missing. Use --help."
INPUT="$1"
}
# --- core logic ---
validate() {
[[ -e "$INPUT" ]] || die "Path does not exist: $INPUT"
verbose "Input validated: $INPUT"
}
process() {
TMPDIR_WORK=$(mktemp -d)
verbose "Working in $TMPDIR_WORK"
# Your main logic here
if "$DRY_RUN"; then
log "DRY RUN: would process $INPUT"
else
log "Processing $INPUT"
fi
}
report() {
log "Done."
}
# --- main ---
main() {
parse_args "$@"
validate
process
report
}
main "$@"
Grading Checklist¶
After writing your script, go through this checklist:
# 1. ShellCheck
shellcheck your_script.sh
# 2. Basic run
bash your_script.sh --help
bash your_script.sh sample_input
# 3. Error handling
bash your_script.sh /nonexistent/path
bash your_script.sh # no args
# 4. Edge cases
bash your_script.sh "file with spaces.txt"
bash your_script.sh --dry-run sample_input
# 5. Interrupt during run
bash your_script.sh long_input &
PID=$!
sleep 1
kill -INT $PID
# Check: are temp files cleaned up?
Submission¶
Push your script to a scripts/ directory in the course repository. Include:
1. The script itself (scripts/capstone_yourname.sh)
2. A scripts/README.md explaining what it does and how to run it
3. A sample input file if applicable