Skip to content

Week 01 Assignment

Apply everything from Week 01 in a single cohesive project: a file inventory script that explores the filesystem, processes text, and produces a report.

Overview

You will write a script called inventory.sh that:

  1. Accepts a directory as a command-line argument (default: current directory)
  2. Scans the directory recursively
  3. Produces a report showing:
  4. Total number of files and directories
  5. Disk usage summary
  6. Top 5 file types by count (based on extension)
  7. Top 5 largest files
  8. Files modified in the last 7 days
  9. Saves the report to a file and prints it to the terminal

Requirements

Your script must demonstrate:

Skill How
Variables Store directory path, counts, timestamps
Control flow Validate directory argument
Loops Iterate over files
Text processing awk, sort, uniq for statistics
I/O redirection tee to write and display simultaneously
find File discovery and filtering
Parameter expansion Extract file extensions
Functions At least 3 named functions

Starter Template

#!/usr/bin/env bash
set -euo pipefail

TARGET="${1:-.}"
REPORT="/tmp/inventory_$(date +%Y%m%d_%H%M%S).txt"

usage() {
    echo "Usage: $0 [DIRECTORY]"
    echo "Generate a file inventory report."
}

validate() {
    [[ -d "$TARGET" ]] || { echo "Error: '$TARGET' is not a directory" >&2; exit 1; }
}

count_items() {
    echo "=== File Counts ==="
    echo "Files:       $(find "$TARGET" -type f | wc -l)"
    echo "Directories: $(find "$TARGET" -type d | wc -l)"
    echo "Symlinks:    $(find "$TARGET" -type l | wc -l)"
}

top_extensions() {
    echo "=== Top 5 File Types ==="
    find "$TARGET" -type f -name "*.*" \
        | awk -F. '{print $NF}' \
        | tr '[:upper:]' '[:lower:]' \
        | sort | uniq -c | sort -rn | head -5
}

largest_files() {
    echo "=== Top 5 Largest Files ==="
    find "$TARGET" -type f -printf "%s\t%p\n" \
        | sort -rn | head -5 \
        | awk '{printf "%10d bytes  %s\n", $1, $2}'
}

recent_files() {
    echo "=== Files Modified in Last 7 Days ==="
    find "$TARGET" -type f -mtime -7 -printf "%TY-%Tm-%Td  %p\n" | sort -r | head -20
}

main() {
    [[ "${1:-}" == "--help" || "${1:-}" == "-h" ]] && { usage; exit 0; }
    validate

    {
        echo "======================================"
        echo " File Inventory Report"
        echo " Directory: $(realpath "$TARGET")"
        echo " Generated: $(date '+%Y-%m-%d %H:%M:%S')"
        echo "======================================"
        echo ""
        count_items
        echo ""
        top_extensions
        echo ""
        largest_files
        echo ""
        recent_files
        echo ""
        echo "Report saved to: $REPORT"
    } | tee "$REPORT"
}

main "$@"

Grading Criteria

Criterion Points
Script runs without errors 20
Correct argument handling (default, missing, invalid) 15
At least 3 functions 15
Report contains all 5 sections 20
Output written to both terminal and file 10
shellcheck passes with no warnings 20
Total 100

Stretch Challenges

  1. Add --json flag that outputs the report as JSON (using printf with manual JSON construction).
  2. Add --compare DIR2 that shows files in DIR1 not in DIR2 and vice versa.
  3. Add color output for warnings (disk usage > 80%, files > 100MB).
  4. Make the report email itself using mail or sendmail if a --email flag is passed.

Submission

  • Submit inventory.sh to the assignments/ directory in the course repository.
  • Include a comment block at the top with your name and a brief description.
  • Run shellcheck inventory.sh and include the (clean) output as a comment or in a README.